1109998Smarkm/* ocsp_lib.c */ 2280297Sjkim/* 3280297Sjkim * Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL 4280297Sjkim * project. 5280297Sjkim */ 6109998Smarkm 7280297Sjkim/* 8280297Sjkim * History: This file was transfered to Richard Levitte from CertCo by Kathy 9280297Sjkim * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a 10280297Sjkim * patch kit. 11280297Sjkim */ 12109998Smarkm 13109998Smarkm/* ==================================================================== 14109998Smarkm * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 15109998Smarkm * 16109998Smarkm * Redistribution and use in source and binary forms, with or without 17109998Smarkm * modification, are permitted provided that the following conditions 18109998Smarkm * are met: 19109998Smarkm * 20109998Smarkm * 1. Redistributions of source code must retain the above copyright 21280297Sjkim * notice, this list of conditions and the following disclaimer. 22109998Smarkm * 23109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 24109998Smarkm * notice, this list of conditions and the following disclaimer in 25109998Smarkm * the documentation and/or other materials provided with the 26109998Smarkm * distribution. 27109998Smarkm * 28109998Smarkm * 3. All advertising materials mentioning features or use of this 29109998Smarkm * software must display the following acknowledgment: 30109998Smarkm * "This product includes software developed by the OpenSSL Project 31109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 32109998Smarkm * 33109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 34109998Smarkm * endorse or promote products derived from this software without 35109998Smarkm * prior written permission. For written permission, please contact 36109998Smarkm * openssl-core@openssl.org. 37109998Smarkm * 38109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 39109998Smarkm * nor may "OpenSSL" appear in their names without prior written 40109998Smarkm * permission of the OpenSSL Project. 41109998Smarkm * 42109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 43109998Smarkm * acknowledgment: 44109998Smarkm * "This product includes software developed by the OpenSSL Project 45109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 46109998Smarkm * 47109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 48109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 50109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 51109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 52109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 53109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 54109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 56109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 57109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 58109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 59109998Smarkm * ==================================================================== 60109998Smarkm * 61109998Smarkm * This product includes cryptographic software written by Eric Young 62109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 63109998Smarkm * Hudson (tjh@cryptsoft.com). 64109998Smarkm * 65109998Smarkm */ 66109998Smarkm 67109998Smarkm#include <stdio.h> 68109998Smarkm#include <cryptlib.h> 69109998Smarkm#include <openssl/objects.h> 70109998Smarkm#include <openssl/rand.h> 71109998Smarkm#include <openssl/x509.h> 72109998Smarkm#include <openssl/pem.h> 73109998Smarkm#include <openssl/x509v3.h> 74109998Smarkm#include <openssl/ocsp.h> 75238405Sjkim#include <openssl/asn1t.h> 76109998Smarkm 77109998Smarkm/* Convert a certificate and its issuer to an OCSP_CERTID */ 78109998Smarkm 79109998SmarkmOCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer) 80109998Smarkm{ 81280297Sjkim X509_NAME *iname; 82280297Sjkim ASN1_INTEGER *serial; 83280297Sjkim ASN1_BIT_STRING *ikey; 84109998Smarkm#ifndef OPENSSL_NO_SHA1 85280297Sjkim if (!dgst) 86280297Sjkim dgst = EVP_sha1(); 87109998Smarkm#endif 88280297Sjkim if (subject) { 89280297Sjkim iname = X509_get_issuer_name(subject); 90280297Sjkim serial = X509_get_serialNumber(subject); 91280297Sjkim } else { 92280297Sjkim iname = X509_get_subject_name(issuer); 93280297Sjkim serial = NULL; 94280297Sjkim } 95280297Sjkim ikey = X509_get0_pubkey_bitstr(issuer); 96280297Sjkim return OCSP_cert_id_new(dgst, iname, ikey, serial); 97109998Smarkm} 98109998Smarkm 99280297SjkimOCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, 100280297Sjkim X509_NAME *issuerName, 101280297Sjkim ASN1_BIT_STRING *issuerKey, 102280297Sjkim ASN1_INTEGER *serialNumber) 103280297Sjkim{ 104280297Sjkim int nid; 105280297Sjkim unsigned int i; 106280297Sjkim X509_ALGOR *alg; 107280297Sjkim OCSP_CERTID *cid = NULL; 108280297Sjkim unsigned char md[EVP_MAX_MD_SIZE]; 109109998Smarkm 110280297Sjkim if (!(cid = OCSP_CERTID_new())) 111280297Sjkim goto err; 112109998Smarkm 113280297Sjkim alg = cid->hashAlgorithm; 114280297Sjkim if (alg->algorithm != NULL) 115280297Sjkim ASN1_OBJECT_free(alg->algorithm); 116280297Sjkim if ((nid = EVP_MD_type(dgst)) == NID_undef) { 117280297Sjkim OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_UNKNOWN_NID); 118280297Sjkim goto err; 119280297Sjkim } 120280297Sjkim if (!(alg->algorithm = OBJ_nid2obj(nid))) 121280297Sjkim goto err; 122280297Sjkim if ((alg->parameter = ASN1_TYPE_new()) == NULL) 123280297Sjkim goto err; 124280297Sjkim alg->parameter->type = V_ASN1_NULL; 125109998Smarkm 126280297Sjkim if (!X509_NAME_digest(issuerName, dgst, md, &i)) 127280297Sjkim goto digerr; 128280297Sjkim if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i))) 129280297Sjkim goto err; 130109998Smarkm 131280297Sjkim /* Calculate the issuerKey hash, excluding tag and length */ 132280297Sjkim if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL)) 133280297Sjkim goto err; 134109998Smarkm 135280297Sjkim if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i))) 136280297Sjkim goto err; 137109998Smarkm 138280297Sjkim if (serialNumber) { 139280297Sjkim ASN1_INTEGER_free(cid->serialNumber); 140280297Sjkim if (!(cid->serialNumber = ASN1_INTEGER_dup(serialNumber))) 141280297Sjkim goto err; 142280297Sjkim } 143280297Sjkim return cid; 144280297Sjkim digerr: 145280297Sjkim OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_DIGEST_ERR); 146280297Sjkim err: 147280297Sjkim if (cid) 148280297Sjkim OCSP_CERTID_free(cid); 149280297Sjkim return NULL; 150280297Sjkim} 151109998Smarkm 152109998Smarkmint OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b) 153280297Sjkim{ 154280297Sjkim int ret; 155280297Sjkim ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm); 156280297Sjkim if (ret) 157280297Sjkim return ret; 158280297Sjkim ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash); 159280297Sjkim if (ret) 160280297Sjkim return ret; 161280297Sjkim return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash); 162280297Sjkim} 163109998Smarkm 164109998Smarkmint OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b) 165280297Sjkim{ 166280297Sjkim int ret; 167280297Sjkim ret = OCSP_id_issuer_cmp(a, b); 168280297Sjkim if (ret) 169280297Sjkim return ret; 170280297Sjkim return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber); 171280297Sjkim} 172109998Smarkm 173280297Sjkim/* 174280297Sjkim * Parse a URL and split it up into host, port and path components and 175280297Sjkim * whether it is SSL. 176109998Smarkm */ 177109998Smarkm 178290207Sjkimint OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, 179280297Sjkim int *pssl) 180280297Sjkim{ 181280297Sjkim char *p, *buf; 182109998Smarkm 183280297Sjkim char *host, *port; 184109998Smarkm 185280297Sjkim *phost = NULL; 186280297Sjkim *pport = NULL; 187280297Sjkim *ppath = NULL; 188237657Sjkim 189280297Sjkim /* dup the buffer since we are going to mess with it */ 190280297Sjkim buf = BUF_strdup(url); 191280297Sjkim if (!buf) 192280297Sjkim goto mem_err; 193109998Smarkm 194280297Sjkim /* Check for initial colon */ 195280297Sjkim p = strchr(buf, ':'); 196109998Smarkm 197280297Sjkim if (!p) 198280297Sjkim goto parse_err; 199109998Smarkm 200280297Sjkim *(p++) = '\0'; 201109998Smarkm 202280297Sjkim if (!strcmp(buf, "http")) { 203280297Sjkim *pssl = 0; 204280297Sjkim port = "80"; 205280297Sjkim } else if (!strcmp(buf, "https")) { 206280297Sjkim *pssl = 1; 207280297Sjkim port = "443"; 208280297Sjkim } else 209280297Sjkim goto parse_err; 210109998Smarkm 211280297Sjkim /* Check for double slash */ 212280297Sjkim if ((p[0] != '/') || (p[1] != '/')) 213280297Sjkim goto parse_err; 214109998Smarkm 215280297Sjkim p += 2; 216109998Smarkm 217280297Sjkim host = p; 218109998Smarkm 219280297Sjkim /* Check for trailing part of path */ 220109998Smarkm 221280297Sjkim p = strchr(p, '/'); 222109998Smarkm 223280297Sjkim if (!p) 224280297Sjkim *ppath = BUF_strdup("/"); 225280297Sjkim else { 226280297Sjkim *ppath = BUF_strdup(p); 227280297Sjkim /* Set start of path to 0 so hostname is valid */ 228280297Sjkim *p = '\0'; 229280297Sjkim } 230109998Smarkm 231280297Sjkim if (!*ppath) 232280297Sjkim goto mem_err; 233109998Smarkm 234280297Sjkim p = host; 235280297Sjkim if (host[0] == '[') { 236280297Sjkim /* ipv6 literal */ 237280297Sjkim host++; 238280297Sjkim p = strchr(host, ']'); 239280297Sjkim if (!p) 240280297Sjkim goto parse_err; 241280297Sjkim *p = '\0'; 242280297Sjkim p++; 243280297Sjkim } 244269682Sjkim 245280297Sjkim /* Look for optional ':' for port number */ 246280297Sjkim if ((p = strchr(p, ':'))) { 247280297Sjkim *p = 0; 248280297Sjkim port = p + 1; 249280297Sjkim } 250109998Smarkm 251280297Sjkim *pport = BUF_strdup(port); 252280297Sjkim if (!*pport) 253280297Sjkim goto mem_err; 254109998Smarkm 255280297Sjkim *phost = BUF_strdup(host); 256109998Smarkm 257280297Sjkim if (!*phost) 258280297Sjkim goto mem_err; 259109998Smarkm 260280297Sjkim OPENSSL_free(buf); 261109998Smarkm 262280297Sjkim return 1; 263109998Smarkm 264280297Sjkim mem_err: 265280297Sjkim OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE); 266280297Sjkim goto err; 267109998Smarkm 268280297Sjkim parse_err: 269280297Sjkim OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL); 270109998Smarkm 271280297Sjkim err: 272280297Sjkim if (buf) 273280297Sjkim OPENSSL_free(buf); 274306195Sjkim if (*ppath) { 275280297Sjkim OPENSSL_free(*ppath); 276306195Sjkim *ppath = NULL; 277306195Sjkim } 278306195Sjkim if (*pport) { 279280297Sjkim OPENSSL_free(*pport); 280306195Sjkim *pport = NULL; 281306195Sjkim } 282306195Sjkim if (*phost) { 283280297Sjkim OPENSSL_free(*phost); 284306195Sjkim *phost = NULL; 285306195Sjkim } 286280297Sjkim return 0; 287109998Smarkm 288280297Sjkim} 289109998Smarkm 290238405SjkimIMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID) 291