1*de5c7f0bStb /* $OpenBSD: ocsp_lib.c,v 1.28 2024/08/28 06:27:19 tb Exp $ */ 2da347917Sbeck /* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL 3da347917Sbeck * project. */ 4da347917Sbeck 5da347917Sbeck /* History: 6da347917Sbeck This file was transfered to Richard Levitte from CertCo by Kathy 7da347917Sbeck Weinhold in mid-spring 2000 to be included in OpenSSL or released 8da347917Sbeck as a patch kit. */ 9da347917Sbeck 10da347917Sbeck /* ==================================================================== 11da347917Sbeck * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 12da347917Sbeck * 13da347917Sbeck * Redistribution and use in source and binary forms, with or without 14da347917Sbeck * modification, are permitted provided that the following conditions 15da347917Sbeck * are met: 16da347917Sbeck * 17da347917Sbeck * 1. Redistributions of source code must retain the above copyright 18da347917Sbeck * notice, this list of conditions and the following disclaimer. 19da347917Sbeck * 20da347917Sbeck * 2. Redistributions in binary form must reproduce the above copyright 21da347917Sbeck * notice, this list of conditions and the following disclaimer in 22da347917Sbeck * the documentation and/or other materials provided with the 23da347917Sbeck * distribution. 24da347917Sbeck * 25da347917Sbeck * 3. All advertising materials mentioning features or use of this 26da347917Sbeck * software must display the following acknowledgment: 27da347917Sbeck * "This product includes software developed by the OpenSSL Project 28da347917Sbeck * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 29da347917Sbeck * 30da347917Sbeck * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 31da347917Sbeck * endorse or promote products derived from this software without 32da347917Sbeck * prior written permission. For written permission, please contact 33da347917Sbeck * openssl-core@openssl.org. 34da347917Sbeck * 35da347917Sbeck * 5. Products derived from this software may not be called "OpenSSL" 36da347917Sbeck * nor may "OpenSSL" appear in their names without prior written 37da347917Sbeck * permission of the OpenSSL Project. 38da347917Sbeck * 39da347917Sbeck * 6. Redistributions of any form whatsoever must retain the following 40da347917Sbeck * acknowledgment: 41da347917Sbeck * "This product includes software developed by the OpenSSL Project 42da347917Sbeck * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 43da347917Sbeck * 44da347917Sbeck * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 45da347917Sbeck * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46da347917Sbeck * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 47da347917Sbeck * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 48da347917Sbeck * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 49da347917Sbeck * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50da347917Sbeck * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 51da347917Sbeck * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52da347917Sbeck * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 53da347917Sbeck * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 54da347917Sbeck * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 55da347917Sbeck * OF THE POSSIBILITY OF SUCH DAMAGE. 56da347917Sbeck * ==================================================================== 57da347917Sbeck * 58da347917Sbeck * This product includes cryptographic software written by Eric Young 59da347917Sbeck * (eay@cryptsoft.com). This product includes software written by Tim 60da347917Sbeck * Hudson (tjh@cryptsoft.com). 61da347917Sbeck * 62da347917Sbeck */ 63da347917Sbeck 64a8913c44Sjsing #include <stdio.h> 65a8913c44Sjsing #include <string.h> 66a8913c44Sjsing 678cf4d6a6Sjsing #include <openssl/opensslconf.h> 688cf4d6a6Sjsing 69b6ab114eSjsing #include <openssl/asn1t.h> 70b6ab114eSjsing #include <openssl/err.h> 71da347917Sbeck #include <openssl/objects.h> 72b6ab114eSjsing #include <openssl/ocsp.h> 73b6ab114eSjsing #include <openssl/pem.h> 74da347917Sbeck #include <openssl/x509.h> 75da347917Sbeck #include <openssl/x509v3.h> 76da347917Sbeck 779f44a700Stb #include "ocsp_local.h" 78a3eeb048Stb #include "x509_local.h" 799f44a700Stb 80da347917Sbeck /* Convert a certificate and its issuer to an OCSP_CERTID */ 81da347917Sbeck 822d2941d0Smiod OCSP_CERTID * 839a659387Stb OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject, const X509 *issuer) 84da347917Sbeck { 85da347917Sbeck X509_NAME *iname; 869a659387Stb const ASN1_INTEGER *serial; 87da347917Sbeck ASN1_BIT_STRING *ikey; 882d2941d0Smiod 89da347917Sbeck #ifndef OPENSSL_NO_SHA1 902d2941d0Smiod if (!dgst) 912d2941d0Smiod dgst = EVP_sha1(); 92da347917Sbeck #endif 932d2941d0Smiod if (subject) { 94da347917Sbeck iname = X509_get_issuer_name(subject); 959a659387Stb serial = X509_get0_serialNumber(subject); 962d2941d0Smiod } else { 97da347917Sbeck iname = X509_get_subject_name(issuer); 98da347917Sbeck serial = NULL; 99da347917Sbeck } 1000c07168cSinoguchi if ((ikey = X509_get0_pubkey_bitstr(issuer)) == NULL) 1010c07168cSinoguchi return NULL; 1020c07168cSinoguchi 103da347917Sbeck return OCSP_cert_id_new(dgst, iname, ikey, serial); 104da347917Sbeck } 105a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_cert_to_id); 106da347917Sbeck 1072d2941d0Smiod OCSP_CERTID * 1084394f12dStb OCSP_cert_id_new(const EVP_MD *dgst, const X509_NAME *issuerName, 1094394f12dStb const ASN1_BIT_STRING *issuerKey, const ASN1_INTEGER *serialNumber) 110da347917Sbeck { 111da347917Sbeck int nid; 112da347917Sbeck unsigned int i; 113da347917Sbeck OCSP_CERTID *cid = NULL; 114da347917Sbeck unsigned char md[EVP_MAX_MD_SIZE]; 115da347917Sbeck 116a3eeb048Stb if ((cid = OCSP_CERTID_new()) == NULL) 1172d2941d0Smiod goto err; 118da347917Sbeck 1192d2941d0Smiod if ((nid = EVP_MD_type(dgst)) == NID_undef) { 1205067ae9fSbeck OCSPerror(OCSP_R_UNKNOWN_NID); 121da347917Sbeck goto err; 122da347917Sbeck } 123a3eeb048Stb if (!X509_ALGOR_set0_by_nid(cid->hashAlgorithm, nid, V_ASN1_NULL, NULL)) 1242d2941d0Smiod goto err; 125da347917Sbeck 126a3eeb048Stb if (!X509_NAME_digest(issuerName, dgst, md, &i)) { 127a3eeb048Stb OCSPerror(OCSP_R_DIGEST_ERR); 128a3eeb048Stb goto err; 129a3eeb048Stb } 130a3eeb048Stb if (!ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i)) 1312d2941d0Smiod goto err; 132da347917Sbeck 133da347917Sbeck /* Calculate the issuerKey hash, excluding tag and length */ 1345cdd308eSdjm if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL)) 1355cdd308eSdjm goto err; 136da347917Sbeck 137a3eeb048Stb if (!ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i)) 1382d2941d0Smiod goto err; 139da347917Sbeck 140a3eeb048Stb if (serialNumber != NULL) { 141da347917Sbeck ASN1_INTEGER_free(cid->serialNumber); 142a3eeb048Stb if ((cid->serialNumber = ASN1_INTEGER_dup(serialNumber)) == NULL) 1432d2941d0Smiod goto err; 144da347917Sbeck } 145a3eeb048Stb 146da347917Sbeck return cid; 147bc775f6cSjsing 148da347917Sbeck err: 1492d2941d0Smiod OCSP_CERTID_free(cid); 150a3eeb048Stb 151da347917Sbeck return NULL; 152da347917Sbeck } 153a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_cert_id_new); 154da347917Sbeck 1552d2941d0Smiod int 1562d2941d0Smiod OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b) 157da347917Sbeck { 158da347917Sbeck int ret; 1592d2941d0Smiod 160*de5c7f0bStb /* 161*de5c7f0bStb * XXX - should we really ignore parameters here? We probably need to 162*de5c7f0bStb * consider omitted parameters and explicit ASN.1 NULL as equal for 163*de5c7f0bStb * the SHAs, so don't blindly switch to X509_ALGOR_cmp(). 164*de5c7f0bStb */ 165da347917Sbeck ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm); 1662d2941d0Smiod if (ret) 1672d2941d0Smiod return ret; 168da347917Sbeck ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash); 1692d2941d0Smiod if (ret) 1702d2941d0Smiod return ret; 171da347917Sbeck return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash); 172da347917Sbeck } 173a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_id_issuer_cmp); 174da347917Sbeck 1752d2941d0Smiod int 1762d2941d0Smiod OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b) 177da347917Sbeck { 178da347917Sbeck int ret; 1792d2941d0Smiod 180da347917Sbeck ret = OCSP_id_issuer_cmp(a, b); 1812d2941d0Smiod if (ret) 1822d2941d0Smiod return ret; 183da347917Sbeck return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber); 184da347917Sbeck } 185a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_id_cmp); 186da347917Sbeck 187da347917Sbeck /* Parse a URL and split it up into host, port and path components and whether 188da347917Sbeck * it is SSL. 189da347917Sbeck */ 1902d2941d0Smiod int 19114edca61Stb OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, 19214edca61Stb int *pssl) 193da347917Sbeck { 19457887ff9Sbeck char *host, *path, *port, *tmp; 195da347917Sbeck 19657887ff9Sbeck *phost = *pport = *ppath = NULL; 197da347917Sbeck *pssl = 0; 19857887ff9Sbeck 19957887ff9Sbeck if (strncmp(url, "https://", 8) == 0) { 200da347917Sbeck *pssl = 1; 20157887ff9Sbeck host = strdup(url + 8); 20257887ff9Sbeck } else if (strncmp(url, "http://", 7) == 0) 20357887ff9Sbeck host = strdup(url + 7); 2042d2941d0Smiod else { 2055067ae9fSbeck OCSPerror(OCSP_R_ERROR_PARSING_URL); 20657887ff9Sbeck return 0; 20757887ff9Sbeck } 20857887ff9Sbeck if (host == NULL) { 2095067ae9fSbeck OCSPerror(ERR_R_MALLOC_FAILURE); 210da347917Sbeck return 0; 211da347917Sbeck } 2120a5d6edeSdjm 21357887ff9Sbeck if ((tmp = strchr(host, '/')) != NULL) { 21457887ff9Sbeck path = strdup(tmp); 21557887ff9Sbeck *tmp = '\0'; 21657887ff9Sbeck } else 21757887ff9Sbeck path = strdup("/"); 21857887ff9Sbeck 21957887ff9Sbeck if ((tmp = strchr(host, ':')) != NULL ) { 22057887ff9Sbeck port = strdup(tmp + 1); 22157887ff9Sbeck *tmp = '\0'; 22257887ff9Sbeck } else { 22357887ff9Sbeck if (*pssl) 22457887ff9Sbeck port = strdup("443"); 22557887ff9Sbeck else 22657887ff9Sbeck port = strdup("80"); 22757887ff9Sbeck } 22857887ff9Sbeck 22957887ff9Sbeck if (path == NULL || port == NULL) { 23057887ff9Sbeck free(host); 23157887ff9Sbeck free(path); 23257887ff9Sbeck free(port); 2335067ae9fSbeck OCSPerror(ERR_R_MALLOC_FAILURE); 23457887ff9Sbeck return 0; 23557887ff9Sbeck } 23657887ff9Sbeck 23757887ff9Sbeck *phost = host; 23857887ff9Sbeck *ppath = path; 23957887ff9Sbeck *pport = port; 24057887ff9Sbeck return 1; 24157887ff9Sbeck } 242a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_parse_url); 2435cfcf2a1Sjsing 2445cfcf2a1Sjsing OCSP_CERTID * 2455cfcf2a1Sjsing OCSP_CERTID_dup(OCSP_CERTID *x) 2465cfcf2a1Sjsing { 247589a2d47Sjsing return ASN1_item_dup(&OCSP_CERTID_it, x); 2485cfcf2a1Sjsing } 249a1e92f6bSbeck LCRYPTO_ALIAS(OCSP_CERTID_dup); 250