CMS support for key agreeement recipient info.
[openssl.git] / crypto / cms / cms_lib.c
index c629baf0e3922d382e4b4cb25e5422075bb366fc..268278014c5820423e86a8775388d4a136e736da 100644 (file)
@@ -52,7 +52,7 @@
  */
 
 #include <openssl/asn1t.h>
-#include <openssl/x509.h>
+#include <openssl/x509v3.h>
 #include <openssl/err.h>
 #include <openssl/pem.h>
 #include <openssl/bio.h>
@@ -341,21 +341,6 @@ int CMS_set_detached(CMS_ContentInfo *cms, int detached)
        return 0;
        }
 
-/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
-
-void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md)
-       {
-       int param_type;
-
-       if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
-               param_type = V_ASN1_UNDEF;
-       else
-               param_type = V_ASN1_NULL;
-
-       X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
-
-       }
-
 /* Create a digest BIO from an X509_ALGOR structure */
 
 BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
@@ -406,11 +391,12 @@ int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
                        return 0;
                        }
                BIO_get_md_ctx(chain, &mtmp);
-               if (EVP_MD_CTX_type(mtmp) == nid)
-                       {
-                       EVP_MD_CTX_copy_ex(mctx, mtmp);
-                       return 1;
-                       }
+               if (EVP_MD_CTX_type(mtmp) == nid
+               /* Workaround for broken implementations that use signature
+                * algorithm  OID instead of digest.
+                */
+                       || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
+                       return EVP_MD_CTX_copy_ex(mctx, mtmp);
                chain = BIO_next(chain);
                }
        }
@@ -548,6 +534,15 @@ int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
        return 1;
        }
 
+int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
+       {
+       int r;
+       r = CMS_add0_crl(cms, crl);
+       if (r > 0)
+               CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
+       return r;
+       }
+
 STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
        {
        STACK_OF(X509) *certs = NULL;
@@ -612,3 +607,62 @@ STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
                }
        return crls;
        }
+
+int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert)
+       {
+       int ret;
+       ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert));
+       if (ret)
+               return ret;
+       return ASN1_INTEGER_cmp(ias->serialNumber, X509_get_serialNumber(cert));
+       }
+
+int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert)
+       {
+       X509_check_purpose(cert, -1, -1);
+       if (!cert->skid)
+               return -1;
+       return ASN1_OCTET_STRING_cmp(keyid, cert->skid);
+       }
+
+int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert)
+       {
+       CMS_IssuerAndSerialNumber *ias;
+       ias = M_ASN1_new_of(CMS_IssuerAndSerialNumber);
+       if (!ias)
+               goto err;
+       if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert)))
+               goto err;
+       if (!ASN1_STRING_copy(ias->serialNumber, X509_get_serialNumber(cert)))
+               goto err;
+       if (*pias)
+               M_ASN1_free_of(*pias, CMS_IssuerAndSerialNumber);
+       *pias = ias;
+       return 1;
+       err:
+       if (ias)
+               M_ASN1_free_of(ias, CMS_IssuerAndSerialNumber);
+       CMSerr(CMS_F_CMS_SET1_IAS, ERR_R_MALLOC_FAILURE);
+       return 0;
+       }
+
+int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert)
+       {
+       ASN1_OCTET_STRING *keyid = NULL;
+       X509_check_purpose(cert, -1, -1);
+       if (!cert->skid)
+               {
+               CMSerr(CMS_F_CMS_SET1_KEYID, CMS_R_CERTIFICATE_HAS_NO_KEYID);
+               return 0;
+               }
+       keyid = ASN1_STRING_dup(cert->skid);
+       if (!keyid)
+               {
+               CMSerr(CMS_F_CMS_SET1_KEYID, ERR_R_MALLOC_FAILURE);
+               return 0;
+               }
+       if (*pkeyid)
+               ASN1_OCTET_STRING_free(*pkeyid);
+       *pkeyid = keyid;
+       return 1;
+       }