Add function PKCS8_set0_pbe
authorDr. Stephen Henson <steve@openssl.org>
Wed, 20 May 2015 23:37:39 +0000 (00:37 +0100)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 26 May 2015 12:09:26 +0000 (13:09 +0100)
This adds a new function which will encrypt a private key using PKCS#8
based on an X509_ALGOR structure and reimplements PKCS8_encrypt to use it.

Update pkcs8 utlity to use PKCS8_set0_pbe.

Reviewed-by: Rich Salz <rsalz@openssl.org>
apps/pkcs8.c
crypto/pkcs12/p12_p8e.c
crypto/pkcs12/pk12err.c
include/openssl/pkcs12.h

index 55c4eea0aa0095297b4247ff468ed5354c65a42b..36e8333c1afb61a300bfd59bd9544f2891cbd69e 100644 (file)
@@ -226,18 +226,30 @@ int pkcs8_main(int argc, char **argv)
                 goto end;
             }
         } else {
+            X509_ALGOR *pbe;
+            if (cipher)
+                pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, 0, NULL, pbe_nid);
+            else
+                pbe = PKCS5_pbe_set(pbe_nid, iter, NULL, 0);
+            if (pbe == NULL) {
+                BIO_printf(bio_err, "Error setting PBE algorithm\n");
+                ERR_print_errors(bio_err);
+                goto end;
+            }
             if (passout)
                 p8pass = passout;
             else {
                 p8pass = pass;
                 if (EVP_read_pw_string
-                    (pass, sizeof pass, "Enter Encryption Password:", 1))
+                    (pass, sizeof pass, "Enter Encryption Password:", 1)) {
+                    X509_ALGOR_free(pbe);
                     goto end;
+                }
             }
             app_RAND_load_file(NULL, 0);
-            if ((p8 = PKCS8_encrypt(pbe_nid, cipher,
-                                    p8pass, strlen(p8pass),
-                                    NULL, 0, iter, p8inf)) == NULL) {
+            p8 = PKCS8_set0_pbe(p8pass, strlen(p8pass), p8inf, pbe);
+            if (p8 == NULL) {
+                X509_ALGOR_free(pbe);
                 BIO_printf(bio_err, "Error encrypting key\n");
                 ERR_print_errors(bio_err);
                 goto end;
index 46ed78a12fe9c466395c63720657abd9f8162528..552f2f0d6189c2ffc53978f2bf760abc127bd06a 100644 (file)
@@ -66,14 +66,9 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
                         unsigned char *salt, int saltlen, int iter,
                         PKCS8_PRIV_KEY_INFO *p8inf)
 {
-    X509_SIG *p8;
+    X509_SIG *p8 = NULL;
     X509_ALGOR *pbe;
 
-    if ((p8 = X509_SIG_new()) == NULL) {
-        PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
-        goto err;
-    }
-
     if (pbe_nid == -1)
         pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
     else if (EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0))
@@ -84,22 +79,40 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
     }
     if (!pbe) {
         PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB);
-        goto err;
+        return NULL;
     }
-    X509_ALGOR_free(p8->algor);
-    p8->algor = pbe;
-    ASN1_OCTET_STRING_free(p8->digest);
-    p8->digest =
+    p8 = PKCS8_set0_pbe(pass, passlen, p8inf, pbe);
+    if (p8 == NULL) {
+        X509_ALGOR_free(pbe);
+        return NULL;
+    }
+
+    return p8;
+}
+
+X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
+                         PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe)
+{
+    X509_SIG *p8;
+    ASN1_OCTET_STRING *enckey;
+
+    enckey =
         PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
                                 pass, passlen, p8inf, 1);
-    if (!p8->digest) {
-        PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR);
-        goto err;
+    if (!enckey) {
+        PKCS12err(PKCS12_F_PKCS8_SET0_PBE, PKCS12_R_ENCRYPT_ERROR);
+        return NULL;
     }
 
-    return p8;
+    if (!(p8 = X509_SIG_new())) {
+        PKCS12err(PKCS12_F_PKCS8_SET0_PBE, ERR_R_MALLOC_FAILURE);
+        ASN1_OCTET_STRING_free(enckey);
+        return NULL;
+    }
+    X509_ALGOR_free(p8->algor);
+    ASN1_OCTET_STRING_free(p8->digest);
+    p8->algor = pbe;
+    p8->digest = enckey;
 
- err:
-    X509_SIG_free(p8);
-    return NULL;
+    return p8;
 }
index e58710b253bcc2f16a663858c2d9d95cf69c3670..4e6c7dd57b2e7dd4648d1d7f31a88925db6ddc38 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/pkcs12/pk12err.c */
 /* ====================================================================
- * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2015 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -101,6 +101,7 @@ static ERR_STRING_DATA PKCS12_str_functs[] = {
     {ERR_FUNC(PKCS12_F_PKCS12_VERIFY_MAC), "PKCS12_verify_mac"},
     {ERR_FUNC(PKCS12_F_PKCS8_ADD_KEYUSAGE), "PKCS8_add_keyusage"},
     {ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT), "PKCS8_encrypt"},
+    {ERR_FUNC(PKCS12_F_PKCS8_SET0_PBE), "PKCS8_set0_pbe"},
     {0, NULL}
 };
 
index e58e55c58a6975f9b694e3c4a5194258de26ffbb..ba8b9441a9a7ac9e2ae892ae77cabf8deb57aa06 100644 (file)
@@ -182,6 +182,8 @@ PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag,
 X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
                         const char *pass, int passlen, unsigned char *salt,
                         int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8);
+X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
+                        PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe);
 PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
                                      int passlen, unsigned char *salt,
                                      int saltlen, int iter,
@@ -309,6 +311,7 @@ void ERR_load_PKCS12_strings(void);
 # define PKCS12_F_PKCS12_VERIFY_MAC                       126
 # define PKCS12_F_PKCS8_ADD_KEYUSAGE                      124
 # define PKCS12_F_PKCS8_ENCRYPT                           125
+# define PKCS12_F_PKCS8_SET0_PBE                          132
 
 /* Reason codes. */
 # define PKCS12_R_CANT_PACK_STRUCTURE                     100