10Sstevel@tonic-gate /* v3_ocsp.c */
20Sstevel@tonic-gate /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
30Sstevel@tonic-gate * project 1999.
40Sstevel@tonic-gate */
50Sstevel@tonic-gate /* ====================================================================
60Sstevel@tonic-gate * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
90Sstevel@tonic-gate * modification, are permitted provided that the following conditions
100Sstevel@tonic-gate * are met:
110Sstevel@tonic-gate *
120Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
130Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
140Sstevel@tonic-gate *
150Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
160Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
170Sstevel@tonic-gate * the documentation and/or other materials provided with the
180Sstevel@tonic-gate * distribution.
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this
210Sstevel@tonic-gate * software must display the following acknowledgment:
220Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
230Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
240Sstevel@tonic-gate *
250Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
260Sstevel@tonic-gate * endorse or promote products derived from this software without
270Sstevel@tonic-gate * prior written permission. For written permission, please contact
280Sstevel@tonic-gate * licensing@OpenSSL.org.
290Sstevel@tonic-gate *
300Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL"
310Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written
320Sstevel@tonic-gate * permission of the OpenSSL Project.
330Sstevel@tonic-gate *
340Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following
350Sstevel@tonic-gate * acknowledgment:
360Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
370Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
380Sstevel@tonic-gate *
390Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
400Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
410Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
420Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
430Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
440Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
450Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
460Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
470Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
480Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
490Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
500Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE.
510Sstevel@tonic-gate * ====================================================================
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young
540Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim
550Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com).
560Sstevel@tonic-gate *
570Sstevel@tonic-gate */
580Sstevel@tonic-gate
590Sstevel@tonic-gate #ifndef OPENSSL_NO_OCSP
600Sstevel@tonic-gate
610Sstevel@tonic-gate #include <stdio.h>
620Sstevel@tonic-gate #include "cryptlib.h"
630Sstevel@tonic-gate #include <openssl/conf.h>
640Sstevel@tonic-gate #include <openssl/asn1.h>
650Sstevel@tonic-gate #include <openssl/ocsp.h>
660Sstevel@tonic-gate #include <openssl/x509v3.h>
670Sstevel@tonic-gate
680Sstevel@tonic-gate /* OCSP extensions and a couple of CRL entry extensions
690Sstevel@tonic-gate */
700Sstevel@tonic-gate
710Sstevel@tonic-gate static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent);
720Sstevel@tonic-gate static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent);
730Sstevel@tonic-gate static int i2r_object(X509V3_EXT_METHOD *method, void *obj, BIO *out, int indent);
740Sstevel@tonic-gate
750Sstevel@tonic-gate static void *ocsp_nonce_new(void);
760Sstevel@tonic-gate static int i2d_ocsp_nonce(void *a, unsigned char **pp);
77*2139Sjp161948 static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length);
780Sstevel@tonic-gate static void ocsp_nonce_free(void *a);
790Sstevel@tonic-gate static int i2r_ocsp_nonce(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent);
800Sstevel@tonic-gate
810Sstevel@tonic-gate static int i2r_ocsp_nocheck(X509V3_EXT_METHOD *method, void *nocheck, BIO *out, int indent);
82*2139Sjp161948 static void *s2i_ocsp_nocheck(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str);
830Sstevel@tonic-gate static int i2r_ocsp_serviceloc(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind);
840Sstevel@tonic-gate
850Sstevel@tonic-gate X509V3_EXT_METHOD v3_ocsp_crlid = {
860Sstevel@tonic-gate NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID),
870Sstevel@tonic-gate 0,0,0,0,
880Sstevel@tonic-gate 0,0,
890Sstevel@tonic-gate 0,0,
900Sstevel@tonic-gate i2r_ocsp_crlid,0,
910Sstevel@tonic-gate NULL
920Sstevel@tonic-gate };
930Sstevel@tonic-gate
940Sstevel@tonic-gate X509V3_EXT_METHOD v3_ocsp_acutoff = {
950Sstevel@tonic-gate NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
960Sstevel@tonic-gate 0,0,0,0,
970Sstevel@tonic-gate 0,0,
980Sstevel@tonic-gate 0,0,
990Sstevel@tonic-gate i2r_ocsp_acutoff,0,
1000Sstevel@tonic-gate NULL
1010Sstevel@tonic-gate };
1020Sstevel@tonic-gate
1030Sstevel@tonic-gate X509V3_EXT_METHOD v3_crl_invdate = {
1040Sstevel@tonic-gate NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
1050Sstevel@tonic-gate 0,0,0,0,
1060Sstevel@tonic-gate 0,0,
1070Sstevel@tonic-gate 0,0,
1080Sstevel@tonic-gate i2r_ocsp_acutoff,0,
1090Sstevel@tonic-gate NULL
1100Sstevel@tonic-gate };
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate X509V3_EXT_METHOD v3_crl_hold = {
1130Sstevel@tonic-gate NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT),
1140Sstevel@tonic-gate 0,0,0,0,
1150Sstevel@tonic-gate 0,0,
1160Sstevel@tonic-gate 0,0,
1170Sstevel@tonic-gate i2r_object,0,
1180Sstevel@tonic-gate NULL
1190Sstevel@tonic-gate };
1200Sstevel@tonic-gate
1210Sstevel@tonic-gate X509V3_EXT_METHOD v3_ocsp_nonce = {
1220Sstevel@tonic-gate NID_id_pkix_OCSP_Nonce, 0, NULL,
1230Sstevel@tonic-gate ocsp_nonce_new,
1240Sstevel@tonic-gate ocsp_nonce_free,
1250Sstevel@tonic-gate d2i_ocsp_nonce,
1260Sstevel@tonic-gate i2d_ocsp_nonce,
1270Sstevel@tonic-gate 0,0,
1280Sstevel@tonic-gate 0,0,
1290Sstevel@tonic-gate i2r_ocsp_nonce,0,
1300Sstevel@tonic-gate NULL
1310Sstevel@tonic-gate };
1320Sstevel@tonic-gate
1330Sstevel@tonic-gate X509V3_EXT_METHOD v3_ocsp_nocheck = {
1340Sstevel@tonic-gate NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL),
1350Sstevel@tonic-gate 0,0,0,0,
1360Sstevel@tonic-gate 0,s2i_ocsp_nocheck,
1370Sstevel@tonic-gate 0,0,
1380Sstevel@tonic-gate i2r_ocsp_nocheck,0,
1390Sstevel@tonic-gate NULL
1400Sstevel@tonic-gate };
1410Sstevel@tonic-gate
1420Sstevel@tonic-gate X509V3_EXT_METHOD v3_ocsp_serviceloc = {
1430Sstevel@tonic-gate NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC),
1440Sstevel@tonic-gate 0,0,0,0,
1450Sstevel@tonic-gate 0,0,
1460Sstevel@tonic-gate 0,0,
1470Sstevel@tonic-gate i2r_ocsp_serviceloc,0,
1480Sstevel@tonic-gate NULL
1490Sstevel@tonic-gate };
1500Sstevel@tonic-gate
i2r_ocsp_crlid(X509V3_EXT_METHOD * method,void * in,BIO * bp,int ind)1510Sstevel@tonic-gate static int i2r_ocsp_crlid(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind)
1520Sstevel@tonic-gate {
1530Sstevel@tonic-gate OCSP_CRLID *a = in;
1540Sstevel@tonic-gate if (a->crlUrl)
1550Sstevel@tonic-gate {
1560Sstevel@tonic-gate if (!BIO_printf(bp, "%*scrlUrl: ", ind, "")) goto err;
1570Sstevel@tonic-gate if (!ASN1_STRING_print(bp, (ASN1_STRING*)a->crlUrl)) goto err;
1580Sstevel@tonic-gate if (!BIO_write(bp, "\n", 1)) goto err;
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate if (a->crlNum)
1610Sstevel@tonic-gate {
1620Sstevel@tonic-gate if (!BIO_printf(bp, "%*scrlNum: ", ind, "")) goto err;
1630Sstevel@tonic-gate if (!i2a_ASN1_INTEGER(bp, a->crlNum)) goto err;
1640Sstevel@tonic-gate if (!BIO_write(bp, "\n", 1)) goto err;
1650Sstevel@tonic-gate }
1660Sstevel@tonic-gate if (a->crlTime)
1670Sstevel@tonic-gate {
1680Sstevel@tonic-gate if (!BIO_printf(bp, "%*scrlTime: ", ind, "")) goto err;
1690Sstevel@tonic-gate if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) goto err;
1700Sstevel@tonic-gate if (!BIO_write(bp, "\n", 1)) goto err;
1710Sstevel@tonic-gate }
1720Sstevel@tonic-gate return 1;
1730Sstevel@tonic-gate err:
1740Sstevel@tonic-gate return 0;
1750Sstevel@tonic-gate }
1760Sstevel@tonic-gate
i2r_ocsp_acutoff(X509V3_EXT_METHOD * method,void * cutoff,BIO * bp,int ind)1770Sstevel@tonic-gate static int i2r_ocsp_acutoff(X509V3_EXT_METHOD *method, void *cutoff, BIO *bp, int ind)
1780Sstevel@tonic-gate {
1790Sstevel@tonic-gate if (!BIO_printf(bp, "%*s", ind, "")) return 0;
1800Sstevel@tonic-gate if(!ASN1_GENERALIZEDTIME_print(bp, cutoff)) return 0;
1810Sstevel@tonic-gate return 1;
1820Sstevel@tonic-gate }
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate
i2r_object(X509V3_EXT_METHOD * method,void * oid,BIO * bp,int ind)1850Sstevel@tonic-gate static int i2r_object(X509V3_EXT_METHOD *method, void *oid, BIO *bp, int ind)
1860Sstevel@tonic-gate {
1870Sstevel@tonic-gate if (!BIO_printf(bp, "%*s", ind, "")) return 0;
1880Sstevel@tonic-gate if(!i2a_ASN1_OBJECT(bp, oid)) return 0;
1890Sstevel@tonic-gate return 1;
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate /* OCSP nonce. This is needs special treatment because it doesn't have
1930Sstevel@tonic-gate * an ASN1 encoding at all: it just contains arbitrary data.
1940Sstevel@tonic-gate */
1950Sstevel@tonic-gate
ocsp_nonce_new(void)1960Sstevel@tonic-gate static void *ocsp_nonce_new(void)
1970Sstevel@tonic-gate {
1980Sstevel@tonic-gate return ASN1_OCTET_STRING_new();
1990Sstevel@tonic-gate }
2000Sstevel@tonic-gate
i2d_ocsp_nonce(void * a,unsigned char ** pp)2010Sstevel@tonic-gate static int i2d_ocsp_nonce(void *a, unsigned char **pp)
2020Sstevel@tonic-gate {
2030Sstevel@tonic-gate ASN1_OCTET_STRING *os = a;
2040Sstevel@tonic-gate if(pp) {
2050Sstevel@tonic-gate memcpy(*pp, os->data, os->length);
2060Sstevel@tonic-gate *pp += os->length;
2070Sstevel@tonic-gate }
2080Sstevel@tonic-gate return os->length;
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate
d2i_ocsp_nonce(void * a,const unsigned char ** pp,long length)211*2139Sjp161948 static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length)
2120Sstevel@tonic-gate {
2130Sstevel@tonic-gate ASN1_OCTET_STRING *os, **pos;
2140Sstevel@tonic-gate pos = a;
2150Sstevel@tonic-gate if(!pos || !*pos) os = ASN1_OCTET_STRING_new();
2160Sstevel@tonic-gate else os = *pos;
2170Sstevel@tonic-gate if(!ASN1_OCTET_STRING_set(os, *pp, length)) goto err;
2180Sstevel@tonic-gate
2190Sstevel@tonic-gate *pp += length;
2200Sstevel@tonic-gate
2210Sstevel@tonic-gate if(pos) *pos = os;
2220Sstevel@tonic-gate return os;
2230Sstevel@tonic-gate
2240Sstevel@tonic-gate err:
2250Sstevel@tonic-gate if(os && (!pos || (*pos != os))) M_ASN1_OCTET_STRING_free(os);
2260Sstevel@tonic-gate OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE);
2270Sstevel@tonic-gate return NULL;
2280Sstevel@tonic-gate }
2290Sstevel@tonic-gate
ocsp_nonce_free(void * a)2300Sstevel@tonic-gate static void ocsp_nonce_free(void *a)
2310Sstevel@tonic-gate {
2320Sstevel@tonic-gate M_ASN1_OCTET_STRING_free(a);
2330Sstevel@tonic-gate }
2340Sstevel@tonic-gate
i2r_ocsp_nonce(X509V3_EXT_METHOD * method,void * nonce,BIO * out,int indent)2350Sstevel@tonic-gate static int i2r_ocsp_nonce(X509V3_EXT_METHOD *method, void *nonce, BIO *out, int indent)
2360Sstevel@tonic-gate {
2370Sstevel@tonic-gate if(BIO_printf(out, "%*s", indent, "") <= 0) return 0;
2380Sstevel@tonic-gate if(i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) return 0;
2390Sstevel@tonic-gate return 1;
2400Sstevel@tonic-gate }
2410Sstevel@tonic-gate
2420Sstevel@tonic-gate /* Nocheck is just a single NULL. Don't print anything and always set it */
2430Sstevel@tonic-gate
i2r_ocsp_nocheck(X509V3_EXT_METHOD * method,void * nocheck,BIO * out,int indent)2440Sstevel@tonic-gate static int i2r_ocsp_nocheck(X509V3_EXT_METHOD *method, void *nocheck, BIO *out, int indent)
2450Sstevel@tonic-gate {
2460Sstevel@tonic-gate return 1;
2470Sstevel@tonic-gate }
2480Sstevel@tonic-gate
s2i_ocsp_nocheck(X509V3_EXT_METHOD * method,X509V3_CTX * ctx,const char * str)249*2139Sjp161948 static void *s2i_ocsp_nocheck(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str)
2500Sstevel@tonic-gate {
2510Sstevel@tonic-gate return ASN1_NULL_new();
2520Sstevel@tonic-gate }
2530Sstevel@tonic-gate
i2r_ocsp_serviceloc(X509V3_EXT_METHOD * method,void * in,BIO * bp,int ind)2540Sstevel@tonic-gate static int i2r_ocsp_serviceloc(X509V3_EXT_METHOD *method, void *in, BIO *bp, int ind)
2550Sstevel@tonic-gate {
2560Sstevel@tonic-gate int i;
2570Sstevel@tonic-gate OCSP_SERVICELOC *a = in;
2580Sstevel@tonic-gate ACCESS_DESCRIPTION *ad;
2590Sstevel@tonic-gate
2600Sstevel@tonic-gate if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0) goto err;
2610Sstevel@tonic-gate if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0) goto err;
2620Sstevel@tonic-gate for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++)
2630Sstevel@tonic-gate {
2640Sstevel@tonic-gate ad = sk_ACCESS_DESCRIPTION_value(a->locator,i);
2650Sstevel@tonic-gate if (BIO_printf(bp, "\n%*s", (2*ind), "") <= 0)
2660Sstevel@tonic-gate goto err;
2670Sstevel@tonic-gate if(i2a_ASN1_OBJECT(bp, ad->method) <= 0) goto err;
2680Sstevel@tonic-gate if(BIO_puts(bp, " - ") <= 0) goto err;
2690Sstevel@tonic-gate if(GENERAL_NAME_print(bp, ad->location) <= 0) goto err;
2700Sstevel@tonic-gate }
2710Sstevel@tonic-gate return 1;
2720Sstevel@tonic-gate err:
2730Sstevel@tonic-gate return 0;
2740Sstevel@tonic-gate }
2750Sstevel@tonic-gate #endif
276