Coverage Report

Created: 2018-08-29 13:53

/src/openssl/crypto/ocsp/ocsp_lib.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the OpenSSL license (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
#include <stdio.h>
11
#include "internal/cryptlib.h"
12
#include <openssl/objects.h>
13
#include <openssl/x509.h>
14
#include <openssl/pem.h>
15
#include <openssl/x509v3.h>
16
#include <openssl/ocsp.h>
17
#include "ocsp_lcl.h"
18
#include <openssl/asn1t.h>
19
20
/* Convert a certificate and its issuer to an OCSP_CERTID */
21
22
OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject,
23
                             const X509 *issuer)
24
0
{
25
0
    X509_NAME *iname;
26
0
    const ASN1_INTEGER *serial;
27
0
    ASN1_BIT_STRING *ikey;
28
0
    if (!dgst)
29
0
        dgst = EVP_sha1();
30
0
    if (subject) {
31
0
        iname = X509_get_issuer_name(subject);
32
0
        serial = X509_get0_serialNumber(subject);
33
0
    } else {
34
0
        iname = X509_get_subject_name(issuer);
35
0
        serial = NULL;
36
0
    }
37
0
    ikey = X509_get0_pubkey_bitstr(issuer);
38
0
    return OCSP_cert_id_new(dgst, iname, ikey, serial);
39
0
}
40
41
OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
42
                              const X509_NAME *issuerName,
43
                              const ASN1_BIT_STRING *issuerKey,
44
                              const ASN1_INTEGER *serialNumber)
45
0
{
46
0
    int nid;
47
0
    unsigned int i;
48
0
    X509_ALGOR *alg;
49
0
    OCSP_CERTID *cid = NULL;
50
0
    unsigned char md[EVP_MAX_MD_SIZE];
51
0
52
0
    if ((cid = OCSP_CERTID_new()) == NULL)
53
0
        goto err;
54
0
55
0
    alg = &cid->hashAlgorithm;
56
0
    ASN1_OBJECT_free(alg->algorithm);
57
0
    if ((nid = EVP_MD_type(dgst)) == NID_undef) {
58
0
        OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_UNKNOWN_NID);
59
0
        goto err;
60
0
    }
61
0
    if ((alg->algorithm = OBJ_nid2obj(nid)) == NULL)
62
0
        goto err;
63
0
    if ((alg->parameter = ASN1_TYPE_new()) == NULL)
64
0
        goto err;
65
0
    alg->parameter->type = V_ASN1_NULL;
66
0
67
0
    if (!X509_NAME_digest(issuerName, dgst, md, &i))
68
0
        goto digerr;
69
0
    if (!(ASN1_OCTET_STRING_set(&cid->issuerNameHash, md, i)))
70
0
        goto err;
71
0
72
0
    /* Calculate the issuerKey hash, excluding tag and length */
73
0
    if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL))
74
0
        goto err;
75
0
76
0
    if (!(ASN1_OCTET_STRING_set(&cid->issuerKeyHash, md, i)))
77
0
        goto err;
78
0
79
0
    if (serialNumber) {
80
0
        if (ASN1_STRING_copy(&cid->serialNumber, serialNumber) == 0)
81
0
            goto err;
82
0
    }
83
0
    return cid;
84
0
 digerr:
85
0
    OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_DIGEST_ERR);
86
0
 err:
87
0
    OCSP_CERTID_free(cid);
88
0
    return NULL;
89
0
}
90
91
int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
92
0
{
93
0
    int ret;
94
0
    ret = OBJ_cmp(a->hashAlgorithm.algorithm, b->hashAlgorithm.algorithm);
95
0
    if (ret)
96
0
        return ret;
97
0
    ret = ASN1_OCTET_STRING_cmp(&a->issuerNameHash, &b->issuerNameHash);
98
0
    if (ret)
99
0
        return ret;
100
0
    return ASN1_OCTET_STRING_cmp(&a->issuerKeyHash, &b->issuerKeyHash);
101
0
}
102
103
int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
104
0
{
105
0
    int ret;
106
0
    ret = OCSP_id_issuer_cmp(a, b);
107
0
    if (ret)
108
0
        return ret;
109
0
    return ASN1_INTEGER_cmp(&a->serialNumber, &b->serialNumber);
110
0
}
111
112
/*
113
 * Parse a URL and split it up into host, port and path components and
114
 * whether it is SSL.
115
 */
116
117
int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath,
118
                   int *pssl)
119
0
{
120
0
    char *p, *buf;
121
0
122
0
    char *host, *port;
123
0
124
0
    *phost = NULL;
125
0
    *pport = NULL;
126
0
    *ppath = NULL;
127
0
128
0
    /* dup the buffer since we are going to mess with it */
129
0
    buf = OPENSSL_strdup(url);
130
0
    if (!buf)
131
0
        goto mem_err;
132
0
133
0
    /* Check for initial colon */
134
0
    p = strchr(buf, ':');
135
0
136
0
    if (!p)
137
0
        goto parse_err;
138
0
139
0
    *(p++) = '\0';
140
0
141
0
    if (strcmp(buf, "http") == 0) {
142
0
        *pssl = 0;
143
0
        port = "80";
144
0
    } else if (strcmp(buf, "https") == 0) {
145
0
        *pssl = 1;
146
0
        port = "443";
147
0
    } else
148
0
        goto parse_err;
149
0
150
0
    /* Check for double slash */
151
0
    if ((p[0] != '/') || (p[1] != '/'))
152
0
        goto parse_err;
153
0
154
0
    p += 2;
155
0
156
0
    host = p;
157
0
158
0
    /* Check for trailing part of path */
159
0
160
0
    p = strchr(p, '/');
161
0
162
0
    if (!p)
163
0
        *ppath = OPENSSL_strdup("/");
164
0
    else {
165
0
        *ppath = OPENSSL_strdup(p);
166
0
        /* Set start of path to 0 so hostname is valid */
167
0
        *p = '\0';
168
0
    }
169
0
170
0
    if (!*ppath)
171
0
        goto mem_err;
172
0
173
0
    p = host;
174
0
    if (host[0] == '[') {
175
0
        /* ipv6 literal */
176
0
        host++;
177
0
        p = strchr(host, ']');
178
0
        if (!p)
179
0
            goto parse_err;
180
0
        *p = '\0';
181
0
        p++;
182
0
    }
183
0
184
0
    /* Look for optional ':' for port number */
185
0
    if ((p = strchr(p, ':'))) {
186
0
        *p = 0;
187
0
        port = p + 1;
188
0
    }
189
0
190
0
    *pport = OPENSSL_strdup(port);
191
0
    if (!*pport)
192
0
        goto mem_err;
193
0
194
0
    *phost = OPENSSL_strdup(host);
195
0
196
0
    if (!*phost)
197
0
        goto mem_err;
198
0
199
0
    OPENSSL_free(buf);
200
0
201
0
    return 1;
202
0
203
0
 mem_err:
204
0
    OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE);
205
0
    goto err;
206
0
207
0
 parse_err:
208
0
    OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL);
209
0
210
0
 err:
211
0
    OPENSSL_free(buf);
212
0
    OPENSSL_free(*ppath);
213
0
    *ppath = NULL;
214
0
    OPENSSL_free(*pport);
215
0
    *pport = NULL;
216
0
    OPENSSL_free(*phost);
217
0
    *phost = NULL;
218
0
    return 0;
219
0
220
0
}
221
222
IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID)