/* Nonce handling functions */
-/* Add a nonce to an OCSP request. A nonce can be specificed or if NULL
+/* Add a nonce to an extension stack. A nonce can be specificed or if NULL
* a random nonce will be generated.
+ * Note: OpenSSL 0.9.7d and later create an OCTET STRING containing the
+ * nonce, previous versions used the raw nonce.
*/
-int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len)
+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;
+ /* Create the OCTET STRING manually by writing out the header and
+ * appending the content octets. This avoids an extra memory allocation
+ * operation in some cases. Applications should *NOT* do this because
+ * it relies on library internals.
+ */
+ os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING);
+ os.data = OPENSSL_malloc(os.length);
+ if (os.data == NULL)
+ goto err;
+ tmpval = os.data;
+ ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
+ if (val)
+ memcpy(tmpval, val, len);
else
- {
- if (!(tmpval = OPENSSL_malloc(len))) goto err;
RAND_pseudo_bytes(tmpval, len);
- }
- os.data = tmpval;
- os.length = len;
- if(!OCSP_REQUEST_add1_ext_i2d(req, NID_id_pkix_OCSP_Nonce,
+ 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);
+ if (os.data)
+ OPENSSL_free(os.data);
return ret;
}
-/* Check nonce validity in a request and response: the nonce
- * must be either absent in both or present and equal in both.
+
+/* 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)
{
/*
* freed immediately anyway.
*/
- int ret = 0, req_idx, resp_idx;
+ 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);
- /* If both absent its OK */
- if((req_idx < 0) && (resp_idx < 0)) return 1;
- if((req_idx < 0) && (resp_idx >= 0))
- {
- OCSPerr(OCSP_F_OCSP_CHECK_NONCE, OCSP_R_NONCE_MISSING_IN_RESPONSE);
- goto err;
- }
+ /* 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))
- {
- OCSPerr(OCSP_F_OCSP_CHECK_NONCE, OCSP_R_UNEXPECTED_NONCE_IN_RESPONSE);
- goto err;
- }
+ 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))
- {
- OCSPerr(OCSP_F_OCSP_CHECK_NONCE, OCSP_R_NONCE_VALUE_MISMATCH);
- goto err;
- }
- ret = 1;
- err:
- return ret;
+ return 0;
+ return 1;
}
-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;
+/* 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)
ASN1_OBJECT *o = NULL;
X509_EXTENSION *x = NULL;
- if (!(sk = sk_ASN1_OBJECT_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)))
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;