X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Focsp%2Focsp_ext.c;h=d6c8899f58e02bc4694b1defffd42228723d58cb;hb=cdb42bcf0cbd5e7625ebab7c3df7caf8eb94764d;hp=60ddc2cff77dadd24283fef254a30c8caec7f8b4;hpb=2f13ee21eae7ba289a80af2d7e4a04e21cc0f0d9;p=oweals%2Fopenssl.git diff --git a/crypto/ocsp/ocsp_ext.c b/crypto/ocsp/ocsp_ext.c index 60ddc2cff7..d6c8899f58 100644 --- a/crypto/ocsp/ocsp_ext.c +++ b/crypto/ocsp/ocsp_ext.c @@ -64,26 +64,209 @@ #include #include #include -#include #include #include +#include #include -/* Make sure we work well with older variants of OpenSSL */ -#ifndef OPENSSL_malloc -#define OPENSSL_malloc Malloc -#endif -#ifndef OPENSSL_realloc -#define OPENSSL_realloc Realloc -#endif -#ifndef OPENSSL_free -#define OPENSSL_free Free -#endif +/* Standard wrapper functions for extensions */ + +/* OCSP request extensions */ + +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x) + { + return(X509v3_get_ext_count(x->tbsRequest->requestExtensions)); + } + +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos) + { + return(X509v3_get_ext_by_NID(x->tbsRequest->requestExtensions,nid,lastpos)); + } + +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos) + { + return(X509v3_get_ext_by_OBJ(x->tbsRequest->requestExtensions,obj,lastpos)); + } + +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos) + { + return(X509v3_get_ext_by_critical(x->tbsRequest->requestExtensions,crit,lastpos)); + } + +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc) + { + return(X509v3_get_ext(x->tbsRequest->requestExtensions,loc)); + } + +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc) + { + return(X509v3_delete_ext(x->tbsRequest->requestExtensions,loc)); + } + +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx) + { + return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx); + } + +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, + unsigned long flags) + { + return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, crit, flags); + } + +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc) + { + return(X509v3_add_ext(&(x->tbsRequest->requestExtensions),ex,loc) != NULL); + } + +/* Single extensions */ + +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x) + { + return(X509v3_get_ext_count(x->singleRequestExtensions)); + } + +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos) + { + return(X509v3_get_ext_by_NID(x->singleRequestExtensions,nid,lastpos)); + } + +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos) + { + return(X509v3_get_ext_by_OBJ(x->singleRequestExtensions,obj,lastpos)); + } + +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos) + { + return(X509v3_get_ext_by_critical(x->singleRequestExtensions,crit,lastpos)); + } + +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc) + { + return(X509v3_get_ext(x->singleRequestExtensions,loc)); + } + +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc) + { + return(X509v3_delete_ext(x->singleRequestExtensions,loc)); + } + +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx) + { + return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx); + } + +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, + unsigned long flags) + { + return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, flags); + } + +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc) + { + return(X509v3_add_ext(&(x->singleRequestExtensions),ex,loc) != NULL); + } + +/* OCSP Basic response */ + +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x) + { + return(X509v3_get_ext_count(x->tbsResponseData->responseExtensions)); + } + +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos) + { + return(X509v3_get_ext_by_NID(x->tbsResponseData->responseExtensions,nid,lastpos)); + } + +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos) + { + return(X509v3_get_ext_by_OBJ(x->tbsResponseData->responseExtensions,obj,lastpos)); + } + +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos) + { + return(X509v3_get_ext_by_critical(x->tbsResponseData->responseExtensions,crit,lastpos)); + } + +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc) + { + return(X509v3_get_ext(x->tbsResponseData->responseExtensions,loc)); + } + +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc) + { + return(X509v3_delete_ext(x->tbsResponseData->responseExtensions,loc)); + } + +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx) + { + return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit, idx); + } + +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit, + unsigned long flags) + { + return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, value, crit, flags); + } + +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc) + { + return(X509v3_add_ext(&(x->tbsResponseData->responseExtensions),ex,loc) != NULL); + } + +/* OCSP single response extensions */ + +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x) + { + return(X509v3_get_ext_count(x->singleExtensions)); + } + +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos) + { + return(X509v3_get_ext_by_NID(x->singleExtensions,nid,lastpos)); + } + +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, int lastpos) + { + return(X509v3_get_ext_by_OBJ(x->singleExtensions,obj,lastpos)); + } + +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos) + { + return(X509v3_get_ext_by_critical(x->singleExtensions,crit,lastpos)); + } + +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc) + { + return(X509v3_get_ext(x->singleExtensions,loc)); + } + +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc) + { + return(X509v3_delete_ext(x->singleExtensions,loc)); + } + +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx) + { + return X509V3_get_d2i(x->singleExtensions, nid, crit, idx); + } + +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit, + unsigned long flags) + { + return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags); + } + +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) + { + return(X509v3_add_ext(&(x->singleExtensions),ex,loc) != NULL); + } /* also CRL Entry Extensions */ ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, int (*i2d)(), - char *data, STACK *sk) + char *data, STACK_OF(ASN1_OBJECT) *sk) { int i; unsigned char *p, *b = NULL; @@ -97,11 +280,11 @@ ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, int (*i2d)(), } else if (sk) { - if ((i=i2d_ASN1_SET(sk,NULL,i2d,V_ASN1_SEQUENCE, + if ((i=i2d_ASN1_SET_OF_ASN1_OBJECT(sk,NULL,i2d,V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL,IS_SEQUENCE))<=0) goto err; if (!(b=p=(unsigned char*)OPENSSL_malloc((unsigned int)i))) goto err; - if (i2d_ASN1_SET(sk,&p,i2d,V_ASN1_SEQUENCE, + if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk,&p,i2d,V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL,IS_SEQUENCE)<=0) goto err; } else @@ -118,16 +301,108 @@ err: return NULL; } -X509_EXTENSION *OCSP_nonce_new(void *p, unsigned int len) - { - X509_EXTENSION *x=NULL; - if (!(x = X509_EXTENSION_new())) goto err; - if (!(x->object = OBJ_nid2obj(NID_id_pkix_OCSP_Nonce))) goto err; - if (!(ASN1_OCTET_STRING_set(x->value, p, len))) goto err; - return x; -err: - if (x) X509_EXTENSION_free(x); - return NULL; +/* Nonce handling functions */ + +/* Add a nonce to an extension stack. A nonce can be specificed or if NULL + * a random nonce will be generated. + */ + +static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, unsigned char *val, int len) + { + unsigned char *tmpval; + ASN1_OCTET_STRING os; + int ret = 0; + if (len <= 0) len = OCSP_DEFAULT_NONCE_LENGTH; + if (val) tmpval = val; + else + { + if (!(tmpval = OPENSSL_malloc(len))) goto err; + RAND_pseudo_bytes(tmpval, len); + } + os.data = tmpval; + os.length = len; + if(!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, + &os, 0, X509V3_ADD_REPLACE)) + goto err; + ret = 1; + err: + if(!val) OPENSSL_free(tmpval); + return ret; + } + + +/* Add nonce to an OCSP request */ + +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) + { + return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len); + } + +/* Same as above but for a response */ + +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) + { + return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, len); + } + +/* Check nonce validity in a request and response. + * Return value reflects result: + * 1: nonces present and equal. + * 2: nonces both absent. + * 3: nonce present in response only. + * 0: nonces both present and not equal. + * -1: nonce in request only. + * + * For most responders clients can check return > 0. + * If responder doesn't handle nonces return != 0 may be + * necessary. return == 0 is always an error. + */ + +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) + { + /* + * Since we are only interested in the presence or absence of + * the nonce and comparing its value there is no need to use + * the X509V3 routines: this way we can avoid them allocating an + * ASN1_OCTET_STRING structure for the value which would be + * freed immediately anyway. + */ + + int req_idx, resp_idx; + X509_EXTENSION *req_ext, *resp_ext; + req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); + resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1); + /* Check both absent */ + if((req_idx < 0) && (resp_idx < 0)) + return 2; + /* Check in request only */ + if((req_idx >= 0) && (resp_idx < 0)) + return -1; + /* Check in response but not request */ + if((req_idx < 0) && (resp_idx >= 0)) + return 3; + /* Otherwise nonce in request and response so retrieve the extensions */ + req_ext = OCSP_REQUEST_get_ext(req, req_idx); + resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx); + if(ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value)) + return 0; + return 1; + } + +/* Copy the nonce value (if any) from an OCSP request to + * a response. + */ + +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req) + { + X509_EXTENSION *req_ext; + int req_idx; + /* Check for nonce in request */ + req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); + /* If no nonce that's OK */ + if (req_idx < 0) return 2; + req_ext = OCSP_REQUEST_get_ext(req, req_idx); + return OCSP_BASICRESP_add_ext(resp, req_ext, -1); } X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim) @@ -146,7 +421,7 @@ X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim) if (!(cid->crlNum = ASN1_INTEGER_new())) goto err; if (!(ASN1_INTEGER_set(cid->crlNum, *n))) goto err; } - if (time) + if (tim) { if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) goto err; if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) @@ -171,11 +446,12 @@ X509_EXTENSION *OCSP_accept_responses_new(char **oids) STACK_OF(ASN1_OBJECT) *sk = NULL; ASN1_OBJECT *o = NULL; X509_EXTENSION *x = NULL; - if (!(sk = sk_new(NULL))) goto err; + + if (!(sk = sk_ASN1_OBJECT_new_null())) goto err; while (oids && *oids) { if ((nid=OBJ_txt2nid(*oids))!=NID_undef&&(o=OBJ_nid2obj(nid))) - sk_push(sk, (char*) o); + sk_ASN1_OBJECT_push(sk, o); oids++; } if (!(x = X509_EXTENSION_new())) goto err; @@ -224,7 +500,7 @@ X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls) if (!(sloc = OCSP_SERVICELOC_new())) goto err; if (!(sloc->issuer = X509_NAME_dup(issuer))) goto err; - if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new(NULL))) goto err; + if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) goto err; while (urls && *urls) { if (!(ad = ACCESS_DESCRIPTION_new())) goto err; @@ -250,99 +526,3 @@ err: return NULL; } -int OCSP_extensions_print(BIO *bp, - STACK_OF(X509_EXTENSION) *sk, - char *title) - { - int i; - if (!sk) return 1; - if (BIO_printf(bp, "%s:\n", title) <= 0) return 0; - for (i=0; iobject)) - { - case NID_id_pkix_OCSP_Nonce: - if (BIO_printf(bp, "%*snonce: ", ind, "") <= 0) - goto err; - if (M_ASN1_OCTET_STRING_print(bp, x->value) <= 0) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) goto err; - break; - case NID_id_pkix_OCSP_CrlID: - if (BIO_printf(bp, "%*scrlId:\n", ind, "") <= 0) - goto err; - p = x->value->data; - if (!(d2i_OCSP_CRLID(&crlid, &p, x->value->length))) - goto err; - if (!OCSP_CRLID_print(bp, crlid, (2*ind))) goto err; - OCSP_CRLID_free(crlid); - break; - case NID_id_pkix_OCSP_acceptableResponses: - if (BIO_printf(bp, - "%*sacceptable responses: ", - ind, "") <= 0) - goto err; - p = x->value->data; - if (!(d2i_ASN1_SET(&sk, &p, x->value->length, - (char *(*)())d2i_ASN1_OBJECT, - (void (*)(void *))ASN1_OBJECT_free, - V_ASN1_SEQUENCE, - V_ASN1_UNIVERSAL))) - goto err; - for (i = 0; i < sk_num(sk); i++) - { - j=OBJ_obj2nid((ASN1_OBJECT*)sk->data[i]); - if (BIO_printf(bp," %s ", - (j == NID_undef)?"UNKNOWN": - OBJ_nid2ln(j)) <= 0) - goto err; - } - if (BIO_write(bp, "\n", 1) <= 0) goto err; - sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); - break; - case NID_id_pkix_OCSP_archiveCutoff: - if (BIO_printf(bp, "%*sarchive cutoff: ", ind, "")<=0) - goto err; - p = x->value->data; - if (!d2i_ASN1_GENERALIZEDTIME(>, &p, - x->value->length)) - goto err; - if (!ASN1_GENERALIZEDTIME_print(bp, gt)) goto err; - if (BIO_write(bp, "\n", 1) <= 0) goto err; - ASN1_GENERALIZEDTIME_free(gt); - break; - case NID_id_pkix_OCSP_serviceLocator: - if (BIO_printf(bp, "%*sservice locator:\n", ind, "") <= 0) - goto err; - p = x->value->data; - if (!d2i_OCSP_SERVICELOC(&sloc, &p, - x->value->length)) - goto err; - if (!OCSP_SERVICELOC_print(bp,sloc,(2*ind))) goto err; - OCSP_SERVICELOC_free(sloc); - break; - case NID_undef: - default: - if (BIO_printf(bp,"%*sunrecognized oid: ",ind,"") <= 0) - goto err; - break; - } - return 1; -err: - return 0; - }