1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/ocsp/ocsp_lib.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,262 @@
1.4 +/* ocsp_lib.c */
1.5 +/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
1.6 + * project. */
1.7 +
1.8 +/* History:
1.9 + This file was transfered to Richard Levitte from CertCo by Kathy
1.10 + Weinhold in mid-spring 2000 to be included in OpenSSL or released
1.11 + as a patch kit. */
1.12 +
1.13 +/* ====================================================================
1.14 + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
1.15 + *
1.16 + * Redistribution and use in source and binary forms, with or without
1.17 + * modification, are permitted provided that the following conditions
1.18 + * are met:
1.19 + *
1.20 + * 1. Redistributions of source code must retain the above copyright
1.21 + * notice, this list of conditions and the following disclaimer.
1.22 + *
1.23 + * 2. Redistributions in binary form must reproduce the above copyright
1.24 + * notice, this list of conditions and the following disclaimer in
1.25 + * the documentation and/or other materials provided with the
1.26 + * distribution.
1.27 + *
1.28 + * 3. All advertising materials mentioning features or use of this
1.29 + * software must display the following acknowledgment:
1.30 + * "This product includes software developed by the OpenSSL Project
1.31 + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
1.32 + *
1.33 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
1.34 + * endorse or promote products derived from this software without
1.35 + * prior written permission. For written permission, please contact
1.36 + * openssl-core@openssl.org.
1.37 + *
1.38 + * 5. Products derived from this software may not be called "OpenSSL"
1.39 + * nor may "OpenSSL" appear in their names without prior written
1.40 + * permission of the OpenSSL Project.
1.41 + *
1.42 + * 6. Redistributions of any form whatsoever must retain the following
1.43 + * acknowledgment:
1.44 + * "This product includes software developed by the OpenSSL Project
1.45 + * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
1.46 + *
1.47 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
1.48 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.49 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1.50 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
1.51 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1.52 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1.53 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1.54 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.55 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1.56 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.57 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1.58 + * OF THE POSSIBILITY OF SUCH DAMAGE.
1.59 + * ====================================================================
1.60 + *
1.61 + * This product includes cryptographic software written by Eric Young
1.62 + * (eay@cryptsoft.com). This product includes software written by Tim
1.63 + * Hudson (tjh@cryptsoft.com).
1.64 + *
1.65 + */
1.66 +
1.67 +#include <stdio.h>
1.68 +#include <cryptlib.h>
1.69 +#include <openssl/objects.h>
1.70 +#include <openssl/rand.h>
1.71 +#include <openssl/x509.h>
1.72 +#include <openssl/pem.h>
1.73 +#include <openssl/x509v3.h>
1.74 +#include <openssl/ocsp.h>
1.75 +
1.76 +/* Convert a certificate and its issuer to an OCSP_CERTID */
1.77 +
1.78 +EXPORT_C OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer)
1.79 +{
1.80 + X509_NAME *iname;
1.81 + ASN1_INTEGER *serial;
1.82 + ASN1_BIT_STRING *ikey;
1.83 +#ifndef OPENSSL_NO_SHA1
1.84 + if(!dgst) dgst = EVP_sha1();
1.85 +#endif
1.86 + if (subject)
1.87 + {
1.88 + iname = X509_get_issuer_name(subject);
1.89 + serial = X509_get_serialNumber(subject);
1.90 + }
1.91 + else
1.92 + {
1.93 + iname = X509_get_subject_name(issuer);
1.94 + serial = NULL;
1.95 + }
1.96 + ikey = X509_get0_pubkey_bitstr(issuer);
1.97 + return OCSP_cert_id_new(dgst, iname, ikey, serial);
1.98 +}
1.99 +
1.100 +
1.101 +EXPORT_C OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
1.102 + X509_NAME *issuerName,
1.103 + ASN1_BIT_STRING* issuerKey,
1.104 + ASN1_INTEGER *serialNumber)
1.105 + {
1.106 + int nid;
1.107 + unsigned int i;
1.108 + X509_ALGOR *alg;
1.109 + OCSP_CERTID *cid = NULL;
1.110 + unsigned char md[EVP_MAX_MD_SIZE];
1.111 +
1.112 + if (!(cid = OCSP_CERTID_new())) goto err;
1.113 +
1.114 + alg = cid->hashAlgorithm;
1.115 + if (alg->algorithm != NULL) ASN1_OBJECT_free(alg->algorithm);
1.116 + if ((nid = EVP_MD_type(dgst)) == NID_undef)
1.117 + {
1.118 + OCSPerr(OCSP_F_OCSP_CERT_ID_NEW,OCSP_R_UNKNOWN_NID);
1.119 + goto err;
1.120 + }
1.121 + if (!(alg->algorithm=OBJ_nid2obj(nid))) goto err;
1.122 + if ((alg->parameter=ASN1_TYPE_new()) == NULL) goto err;
1.123 + alg->parameter->type=V_ASN1_NULL;
1.124 +
1.125 + if (!X509_NAME_digest(issuerName, dgst, md, &i)) goto digerr;
1.126 + if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i))) goto err;
1.127 +
1.128 + /* Calculate the issuerKey hash, excluding tag and length */
1.129 + EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL);
1.130 +
1.131 + if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i))) goto err;
1.132 +
1.133 + if (serialNumber)
1.134 + {
1.135 + ASN1_INTEGER_free(cid->serialNumber);
1.136 + if (!(cid->serialNumber = ASN1_INTEGER_dup(serialNumber))) goto err;
1.137 + }
1.138 + return cid;
1.139 +digerr:
1.140 + OCSPerr(OCSP_F_OCSP_CERT_ID_NEW,OCSP_R_DIGEST_ERR);
1.141 +err:
1.142 + if (cid) OCSP_CERTID_free(cid);
1.143 + return NULL;
1.144 + }
1.145 +
1.146 +EXPORT_C int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
1.147 + {
1.148 + int ret;
1.149 + ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm);
1.150 + if (ret) return ret;
1.151 + ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash);
1.152 + if (ret) return ret;
1.153 + return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash);
1.154 + }
1.155 +
1.156 +EXPORT_C int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
1.157 + {
1.158 + int ret;
1.159 + ret = OCSP_id_issuer_cmp(a, b);
1.160 + if (ret) return ret;
1.161 + return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber);
1.162 + }
1.163 +
1.164 +
1.165 +/* Parse a URL and split it up into host, port and path components and whether
1.166 + * it is SSL.
1.167 + */
1.168 +
1.169 +EXPORT_C int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl)
1.170 + {
1.171 + char *p, *buf;
1.172 +
1.173 + char *host, *port;
1.174 +
1.175 + /* dup the buffer since we are going to mess with it */
1.176 + buf = BUF_strdup(url);
1.177 + if (!buf) goto mem_err;
1.178 +
1.179 + *phost = NULL;
1.180 + *pport = NULL;
1.181 + *ppath = NULL;
1.182 +
1.183 + /* Check for initial colon */
1.184 + p = strchr(buf, ':');
1.185 +
1.186 + if (!p) goto parse_err;
1.187 +
1.188 + *(p++) = '\0';
1.189 +
1.190 + if (!strcmp(buf, "http"))
1.191 + {
1.192 + *pssl = 0;
1.193 + port = "80";
1.194 + }
1.195 + else if (!strcmp(buf, "https"))
1.196 + {
1.197 + *pssl = 1;
1.198 + port = "443";
1.199 + }
1.200 + else
1.201 + goto parse_err;
1.202 +
1.203 + /* Check for double slash */
1.204 + if ((p[0] != '/') || (p[1] != '/'))
1.205 + goto parse_err;
1.206 +
1.207 + p += 2;
1.208 +
1.209 + host = p;
1.210 +
1.211 + /* Check for trailing part of path */
1.212 +
1.213 + p = strchr(p, '/');
1.214 +
1.215 + if (!p)
1.216 + *ppath = BUF_strdup("/");
1.217 + else
1.218 + {
1.219 + *ppath = BUF_strdup(p);
1.220 + /* Set start of path to 0 so hostname is valid */
1.221 + *p = '\0';
1.222 + }
1.223 +
1.224 + if (!*ppath) goto mem_err;
1.225 +
1.226 + /* Look for optional ':' for port number */
1.227 + if ((p = strchr(host, ':')))
1.228 + {
1.229 + *p = 0;
1.230 + port = p + 1;
1.231 + }
1.232 + else
1.233 + {
1.234 + /* Not found: set default port */
1.235 + if (*pssl) port = "443";
1.236 + else port = "80";
1.237 + }
1.238 +
1.239 + *pport = BUF_strdup(port);
1.240 + if (!*pport) goto mem_err;
1.241 +
1.242 + *phost = BUF_strdup(host);
1.243 +
1.244 + if (!*phost) goto mem_err;
1.245 +
1.246 + OPENSSL_free(buf);
1.247 +
1.248 + return 1;
1.249 +
1.250 + mem_err:
1.251 + OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE);
1.252 + goto err;
1.253 +
1.254 + parse_err:
1.255 + OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL);
1.256 +
1.257 +
1.258 + err:
1.259 + if (buf) OPENSSL_free(buf);
1.260 + if (*ppath) OPENSSL_free(*ppath);
1.261 + if (*pport) OPENSSL_free(*pport);
1.262 + if (*phost) OPENSSL_free(*phost);
1.263 + return 0;
1.264 +
1.265 + }