GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/ocsp/ocsp_lib.c Lines: 56 83 67.5 %
Date: 2017-11-07 Branches: 24 48 50.0 %

Line Branch Exec Source
1
/* $OpenBSD: ocsp_lib.c,v 1.20 2017/01/29 17:49:23 beck Exp $ */
2
/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
3
 * project. */
4
5
/* History:
6
   This file was transfered to Richard Levitte from CertCo by Kathy
7
   Weinhold in mid-spring 2000 to be included in OpenSSL or released
8
   as a patch kit. */
9
10
/* ====================================================================
11
 * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
12
 *
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions
15
 * are met:
16
 *
17
 * 1. Redistributions of source code must retain the above copyright
18
 *    notice, this list of conditions and the following disclaimer.
19
 *
20
 * 2. Redistributions in binary form must reproduce the above copyright
21
 *    notice, this list of conditions and the following disclaimer in
22
 *    the documentation and/or other materials provided with the
23
 *    distribution.
24
 *
25
 * 3. All advertising materials mentioning features or use of this
26
 *    software must display the following acknowledgment:
27
 *    "This product includes software developed by the OpenSSL Project
28
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
29
 *
30
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
31
 *    endorse or promote products derived from this software without
32
 *    prior written permission. For written permission, please contact
33
 *    openssl-core@openssl.org.
34
 *
35
 * 5. Products derived from this software may not be called "OpenSSL"
36
 *    nor may "OpenSSL" appear in their names without prior written
37
 *    permission of the OpenSSL Project.
38
 *
39
 * 6. Redistributions of any form whatsoever must retain the following
40
 *    acknowledgment:
41
 *    "This product includes software developed by the OpenSSL Project
42
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
43
 *
44
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
45
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
48
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55
 * OF THE POSSIBILITY OF SUCH DAMAGE.
56
 * ====================================================================
57
 *
58
 * This product includes cryptographic software written by Eric Young
59
 * (eay@cryptsoft.com).  This product includes software written by Tim
60
 * Hudson (tjh@cryptsoft.com).
61
 *
62
 */
63
64
#include <stdio.h>
65
#include <string.h>
66
67
#include <openssl/opensslconf.h>
68
69
#include <openssl/asn1t.h>
70
#include <openssl/err.h>
71
#include <openssl/objects.h>
72
#include <openssl/ocsp.h>
73
#include <openssl/pem.h>
74
#include <openssl/x509.h>
75
#include <openssl/x509v3.h>
76
77
/* Convert a certificate and its issuer to an OCSP_CERTID */
78
79
OCSP_CERTID *
80
OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer)
81
{
82
	X509_NAME *iname;
83
	ASN1_INTEGER *serial;
84
	ASN1_BIT_STRING *ikey;
85
86
#ifndef OPENSSL_NO_SHA1
87
32
	if (!dgst)
88
		dgst = EVP_sha1();
89
#endif
90
16
	if (subject) {
91
8
		iname = X509_get_issuer_name(subject);
92
8
		serial = X509_get_serialNumber(subject);
93
8
	} else {
94
8
		iname = X509_get_subject_name(issuer);
95
		serial = NULL;
96
	}
97
16
	ikey = X509_get0_pubkey_bitstr(issuer);
98
16
	return OCSP_cert_id_new(dgst, iname, ikey, serial);
99
}
100
101
OCSP_CERTID *
102
OCSP_cert_id_new(const EVP_MD *dgst, X509_NAME *issuerName,
103
    ASN1_BIT_STRING* issuerKey, ASN1_INTEGER *serialNumber)
104
{
105
	int nid;
106
32
	unsigned int i;
107
	X509_ALGOR *alg;
108
	OCSP_CERTID *cid = NULL;
109
16
	unsigned char md[EVP_MAX_MD_SIZE];
110
111
16
	if (!(cid = OCSP_CERTID_new()))
112
		goto err;
113
114
16
	alg = cid->hashAlgorithm;
115
16
	if (alg->algorithm != NULL)
116
16
		ASN1_OBJECT_free(alg->algorithm);
117
16
	if ((nid = EVP_MD_type(dgst)) == NID_undef) {
118
		OCSPerror(OCSP_R_UNKNOWN_NID);
119
		goto err;
120
	}
121
16
	if (!(alg->algorithm = OBJ_nid2obj(nid)))
122
		goto err;
123
16
	if ((alg->parameter = ASN1_TYPE_new()) == NULL)
124
		goto err;
125
16
	alg->parameter->type = V_ASN1_NULL;
126
127
16
	if (!X509_NAME_digest(issuerName, dgst, md, &i))
128
		goto digerr;
129
16
	if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i)))
130
		goto err;
131
132
	/* Calculate the issuerKey hash, excluding tag and length */
133
16
	if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL))
134
		goto err;
135
136
16
	if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i)))
137
		goto err;
138
139
16
	if (serialNumber) {
140
8
		ASN1_INTEGER_free(cid->serialNumber);
141
8
		if (!(cid->serialNumber = ASN1_INTEGER_dup(serialNumber)))
142
			goto err;
143
	}
144
16
	return cid;
145
146
digerr:
147
	OCSPerror(OCSP_R_DIGEST_ERR);
148
err:
149
	if (cid)
150
		OCSP_CERTID_free(cid);
151
	return NULL;
152
16
}
153
154
int
155
OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
156
{
157
	int ret;
158
159
36
	ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm);
160
18
	if (ret)
161
		return ret;
162
18
	ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash);
163
18
	if (ret)
164
		return ret;
165
18
	return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash);
166
18
}
167
168
int
169
OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
170
{
171
	int ret;
172
173
12
	ret = OCSP_id_issuer_cmp(a, b);
174
6
	if (ret)
175
		return ret;
176
6
	return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber);
177
6
}
178
179
/* Parse a URL and split it up into host, port and path components and whether
180
 * it is SSL.
181
 */
182
int
183
OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl)
184
{
185
	char *host, *path, *port, *tmp;
186
187
4
	*phost = *pport = *ppath = NULL;
188
2
	*pssl = 0;
189
190
2
	if (strncmp(url, "https://", 8) == 0) {
191
		*pssl = 1;
192
		host = strdup(url + 8);
193
2
	} else if (strncmp(url, "http://", 7) == 0)
194
2
		host = strdup(url + 7);
195
	else {
196
		OCSPerror(OCSP_R_ERROR_PARSING_URL);
197
		return 0;
198
	}
199
2
	if (host == NULL) {
200
		OCSPerror(ERR_R_MALLOC_FAILURE);
201
		return 0;
202
	}
203
204
2
	if ((tmp = strchr(host, '/')) != NULL) {
205
		path = strdup(tmp);
206
		*tmp = '\0';
207
	} else
208
2
		path = strdup("/");
209
210
2
	if ((tmp = strchr(host, ':')) != NULL ) {
211
2
		port = strdup(tmp + 1);
212
2
		*tmp = '\0';
213
2
	} else {
214
		if (*pssl)
215
			port = strdup("443");
216
		else
217
			port = strdup("80");
218
	}
219
220
2
	if (path == NULL || port == NULL) {
221
		free(host);
222
		free(path);
223
		free(port);
224
		OCSPerror(ERR_R_MALLOC_FAILURE);
225
		return 0;
226
	}
227
228
2
	*phost = host;
229
2
	*ppath = path;
230
2
	*pport = port;
231
2
	return 1;
232
2
}
233
234
OCSP_CERTID *
235
OCSP_CERTID_dup(OCSP_CERTID *x)
236
{
237
16
	return ASN1_item_dup(&OCSP_CERTID_it, x);
238
}