Certificate Management Protocol (CMP, RFC 4210) extension to OpenSSL
[oweals/openssl.git] / crypto / crmf / crmf_lib.c
index 297434144691530b6cdbd2fd9031b847c11d338c..85444017ffd10a017803c433674ca2adca274dca 100644 (file)
@@ -82,16 +82,14 @@ static int OSSL_CRMF_MSG_push0_regCtrl(OSSL_CRMF_MSG *crm,
     if (crm->certReq->controls == NULL) {
         crm->certReq->controls = sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new_null();
         if (crm->certReq->controls == NULL)
-            goto oom;
+            goto err;
         new = 1;
     }
     if (!sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_push(crm->certReq->controls, ctrl))
-        goto oom;
+        goto err;
 
     return 1;
- oom:
-    CRMFerr(CRMF_F_OSSL_CRMF_MSG_PUSH0_REGCTRL, ERR_R_MALLOC_FAILURE);
-
+ err:
     if (new != 0) {
         sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free(crm->certReq->controls);
         crm->certReq->controls = NULL;
@@ -136,16 +134,9 @@ int OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo(
     if (pi->pubInfos == NULL)
         pi->pubInfos = sk_OSSL_CRMF_SINGLEPUBINFO_new_null();
     if (pi->pubInfos == NULL)
-        goto oom;
-
-    if (!sk_OSSL_CRMF_SINGLEPUBINFO_push(pi->pubInfos, spi))
-        goto oom;
-    return 1;
+        return 0;
 
- oom:
-    CRMFerr(CRMF_F_OSSL_CRMF_MSG_PKIPUBLICATIONINFO_PUSH0_SINGLEPUBINFO,
-            ERR_R_MALLOC_FAILURE);
-    return 0;
+    return sk_OSSL_CRMF_SINGLEPUBINFO_push(pi->pubInfos, spi);
 }
 
 int OSSL_CRMF_MSG_set_PKIPublicationInfo_action(
@@ -180,20 +171,19 @@ OSSL_CRMF_CERTID *OSSL_CRMF_CERTID_gen(const X509_NAME *issuer,
     }
 
     if ((cid = OSSL_CRMF_CERTID_new()) == NULL)
-        goto oom;
+        goto err;
 
     if (!X509_NAME_set(&cid->issuer->d.directoryName, issuer))
-        goto oom;
+        goto err;
     cid->issuer->type = GEN_DIRNAME;
 
     ASN1_INTEGER_free(cid->serialNumber);
     if ((cid->serialNumber = ASN1_INTEGER_dup(serial)) == NULL)
-        goto oom;
+        goto err;
 
     return cid;
 
- oom:
-    CRMFerr(CRMF_F_OSSL_CRMF_CERTID_GEN, ERR_R_MALLOC_FAILURE);
+ err:
     OSSL_CRMF_CERTID_free(cid);
     return NULL;
 }
@@ -222,13 +212,12 @@ static int OSSL_CRMF_MSG_push0_regInfo(OSSL_CRMF_MSG *crm,
     if (crm->regInfo == NULL)
         crm->regInfo = info = sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_new_null();
     if (crm->regInfo == NULL)
-        goto oom;
+        goto err;
     if (!sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_push(crm->regInfo, ri))
-        goto oom;
+        goto err;
     return 1;
 
- oom:
-    CRMFerr(CRMF_F_OSSL_CRMF_MSG_PUSH0_REGINFO, ERR_R_MALLOC_FAILURE);
+ err:
     if (info != NULL)
         crm->regInfo = NULL;
     sk_OSSL_CRMF_ATTRIBUTETYPEANDVALUE_free(info);
@@ -266,11 +255,11 @@ int OSSL_CRMF_MSG_set_validity(OSSL_CRMF_MSG *crm, time_t from, time_t to)
     }
 
     if (from != 0 && ((from_asn = ASN1_TIME_set(NULL, from)) == NULL))
-        goto oom;
+        goto err;
     if (to != 0 && ((to_asn = ASN1_TIME_set(NULL, to)) == NULL))
-        goto oom;
+        goto err;
     if ((vld = OSSL_CRMF_OPTIONALVALIDITY_new()) == NULL)
-        goto oom;
+        goto err;
 
     vld->notBefore = from_asn;
     vld->notAfter = to_asn;
@@ -278,8 +267,7 @@ int OSSL_CRMF_MSG_set_validity(OSSL_CRMF_MSG *crm, time_t from, time_t to)
     tmpl->validity = vld;
 
     return 1;
- oom:
-    CRMFerr(CRMF_F_OSSL_CRMF_MSG_SET_VALIDITY, ERR_R_MALLOC_FAILURE);
+ err:
     ASN1_TIME_free(from_asn);
     ASN1_TIME_free(to_asn);
     return 0;
@@ -348,7 +336,7 @@ int OSSL_CRMF_MSG_set0_extensions(OSSL_CRMF_MSG *crm,
 
 
 int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm,
-                                  const X509_EXTENSION *ext)
+                                  X509_EXTENSION *ext)
 {
     int new = 0;
     OSSL_CRMF_CERTTEMPLATE *tmpl = OSSL_CRMF_MSG_get0_tmpl(crm);
@@ -360,16 +348,14 @@ int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm,
 
     if (tmpl->extensions == NULL) {
         if ((tmpl->extensions = sk_X509_EXTENSION_new_null()) == NULL)
-            goto oom;
+            goto err;
         new = 1;
     }
 
-    if (!sk_X509_EXTENSION_push(tmpl->extensions, (X509_EXTENSION *)ext))
-        goto oom;
+    if (!sk_X509_EXTENSION_push(tmpl->extensions, ext))
+        goto err;
     return 1;
- oom:
-    CRMFerr(CRMF_F_OSSL_CRMF_MSG_PUSH0_EXTENSION, ERR_R_MALLOC_FAILURE);
-
+ err:
     if (new != 0) {
         sk_X509_EXTENSION_free(tmpl->extensions);
         tmpl->extensions = NULL;
@@ -428,10 +414,8 @@ static int CRMF_poposigningkey_init(OSSL_CRMF_POPOSIGNINGKEY *ps,
         CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_ERROR);
         goto err;
     }
-    if ((sig = OPENSSL_malloc(siglen)) == NULL) {
-        CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, ERR_R_MALLOC_FAILURE);
+    if ((sig = OPENSSL_malloc(siglen)) == NULL)
         goto err;
-    }
     if (EVP_DigestSignFinal(ctx, sig, &siglen) <= 0
             || !ASN1_BIT_STRING_set(ps->signature, sig, siglen)) {
         CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_ERROR);
@@ -461,13 +445,13 @@ int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
     if (ppmtd == OSSL_CRMF_POPO_NONE)
         goto end;
     if ((pp = OSSL_CRMF_POPO_new()) == NULL)
-        goto oom;
+        goto err;
     pp->type = ppmtd;
 
     switch (ppmtd) {
     case OSSL_CRMF_POPO_RAVERIFIED:
         if ((pp->value.raVerified = ASN1_NULL_new()) == NULL)
-            goto oom;
+            goto err;
         break;
 
     case OSSL_CRMF_POPO_SIGNATURE:
@@ -484,14 +468,14 @@ int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
 
     case OSSL_CRMF_POPO_KEYENC:
         if ((pp->value.keyEncipherment = OSSL_CRMF_POPOPRIVKEY_new()) == NULL)
-            goto oom;
+            goto err;
         tag = ASN1_INTEGER_new();
         pp->value.keyEncipherment->type =
             OSSL_CRMF_POPOPRIVKEY_SUBSEQUENTMESSAGE;
         pp->value.keyEncipherment->value.subsequentMessage = tag;
         if (tag == NULL
                 || !ASN1_INTEGER_set(tag, OSSL_CRMF_SUBSEQUENTMESSAGE_ENCRCERT))
-            goto oom;
+            goto err;
         break;
 
     default:
@@ -505,8 +489,6 @@ int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey,
     crm->popo = pp;
 
     return 1;
- oom:
-    CRMFerr(CRMF_F_OSSL_CRMF_MSG_CREATE_POPO, ERR_R_MALLOC_FAILURE);
  err:
     OSSL_CRMF_POPO_free(pp);
     return 0;
@@ -609,7 +591,20 @@ X509_NAME *OSSL_CRMF_CERTTEMPLATE_get0_issuer(OSSL_CRMF_CERTTEMPLATE *tmpl)
     return tmpl != NULL ? tmpl->issuer : NULL;
 }
 
-/*
+/* retrieves the issuer name of the given CertId or NULL on error */
+X509_NAME *OSSL_CRMF_CERTID_get0_issuer(const OSSL_CRMF_CERTID *cid)
+{
+    return cid != NULL && cid->issuer->type == GEN_DIRNAME ?
+        cid->issuer->d.directoryName : NULL;
+}
+
+/* retrieves the serialNumber of the given CertId or NULL on error */
+ASN1_INTEGER *OSSL_CRMF_CERTID_get0_serialNumber(const OSSL_CRMF_CERTID *cid)
+{
+    return cid != NULL ? cid->serialNumber : NULL;
+}
+
+/*-
  * fill in certificate template.
  * Any value argument that is NULL will leave the respective field unchanged.
  */
@@ -624,27 +619,23 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
         return 0;
     }
     if (subject != NULL && !X509_NAME_set(&tmpl->subject, subject))
-        goto oom;
+        return 0;
     if (issuer != NULL && !X509_NAME_set(&tmpl->issuer, issuer))
-        goto oom;
+        return 0;
     if (serial != NULL) {
         ASN1_INTEGER_free(tmpl->serialNumber);
         if ((tmpl->serialNumber = ASN1_INTEGER_dup(serial)) == NULL)
-            goto oom;
+            return 0;
     }
     if (pubkey != NULL && !X509_PUBKEY_set(&tmpl->publicKey, pubkey))
-        goto oom;
+        return 0;
     return 1;
-
- oom:
-    CRMFerr(CRMF_F_OSSL_CRMF_CERTTEMPLATE_FILL, ERR_R_MALLOC_FAILURE);
-    return 0;
 }
 
 
 /*-
- * Decrypts the certificate in the given encryptedValue
- * this is needed for the indirect PoP method as in RFC 4210 section 5.2.8.2
+ * Decrypts the certificate in the given encryptedValue using private key pkey.
+ * This is needed for the indirect PoP method as in RFC 4210 section 5.2.8.2.
  *
  * returns a pointer to the decrypted certificate
  * returns NULL on error or if no certificate available
@@ -693,7 +684,7 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert,
         if (EVP_PKEY_decrypt(pkctx, NULL, &eksize,
                              encKey->data, encKey->length) <= 0
                 || (ek = OPENSSL_malloc(eksize)) == NULL)
-            goto oom;
+            goto end;
         retval = EVP_PKEY_decrypt(pkctx, ek, &eksize,
                                   encKey->data, encKey->length);
         ERR_clear_error(); /* error state may have sensitive information */
@@ -706,10 +697,10 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert,
             goto end;
         }
     } else {
-        goto oom;
+        goto end;
     }
     if ((iv = OPENSSL_malloc(EVP_CIPHER_iv_length(cipher))) == NULL)
-        goto oom;
+        goto end;
     if (ASN1_TYPE_get_octetstring(ecert->symmAlg->parameter, iv,
                                    EVP_CIPHER_iv_length(cipher))
         != EVP_CIPHER_iv_length(cipher)) {
@@ -725,7 +716,7 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert,
     if ((p = outbuf = OPENSSL_malloc(ecert->encValue->length +
                                      EVP_CIPHER_block_size(cipher))) == NULL
             || (evp_ctx = EVP_CIPHER_CTX_new()) == NULL)
-        goto oom;
+        goto end;
     EVP_CIPHER_CTX_set_padding(evp_ctx, 0);
 
     if (!EVP_DecryptInit(evp_ctx, cipher, ek, iv)
@@ -744,10 +735,6 @@ X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert,
         CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT,
                 CRMF_R_ERROR_DECODING_CERTIFICATE);
     }
-    goto end;
-
- oom:
-    CRMFerr(CRMF_F_OSSL_CRMF_ENCRYPTEDVALUE_GET1_ENCCERT, ERR_R_MALLOC_FAILURE);
  end:
     EVP_PKEY_CTX_free(pkctx);
     OPENSSL_free(outbuf);