crypto/pkcs12: facilitate accessing data with non-interoperable password.
[openssl.git] / crypto / pkcs12 / p12_crpt.c
index 1fe140ad0a5150e45a5e102cb0ea96cec0ea5484..d30aab379adb991750bde32ba3e094b9d3279c94 100644 (file)
@@ -17,6 +17,16 @@ void PKCS12_PBE_add(void)
 {
 }
 
+#undef PKCS12_key_gen
+/*
+ * See p12_multi.c:PKCS12_verify_mac() for details...
+ */
+extern int (*PKCS12_key_gen)(const char *pass, int passlen,
+                             unsigned char *salt, int slen,
+                             int id, int iter, int n,
+                             unsigned char *out,
+                             const EVP_MD *md_type);
+
 int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
                         ASN1_TYPE *param, const EVP_CIPHER *cipher,
                         const EVP_MD *md, int en_de)
@@ -25,6 +35,19 @@ int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
     int saltlen, iter, ret;
     unsigned char *salt;
     unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
+    int (*pkcs12_key_gen)(const char *pass, int passlen,
+                          unsigned char *salt, int slen,
+                          int id, int iter, int n,
+                          unsigned char *out,
+                          const EVP_MD *md_type);
+
+    if (PKCS12_key_gen == NULL || en_de)
+        /*
+         * Default to UTF-8, but force it in encrypt case.
+         */
+        pkcs12_key_gen = PKCS12_key_gen_utf8;
+    else
+        pkcs12_key_gen = PKCS12_key_gen;
 
     if (cipher == NULL)
         return 0;
@@ -43,14 +66,14 @@ int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
         iter = ASN1_INTEGER_get(pbe->iter);
     salt = pbe->salt->data;
     saltlen = pbe->salt->length;
-    if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_KEY_ID,
-                        iter, EVP_CIPHER_key_length(cipher), key, md)) {
+    if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_KEY_ID,
+                           iter, EVP_CIPHER_key_length(cipher), key, md)) {
         PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_KEY_GEN_ERROR);
         PBEPARAM_free(pbe);
         return 0;
     }
-    if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_IV_ID,
-                        iter, EVP_CIPHER_iv_length(cipher), iv, md)) {
+    if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_IV_ID,
+                           iter, EVP_CIPHER_iv_length(cipher), iv, md)) {
         PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_IV_GEN_ERROR);
         PBEPARAM_free(pbe);
         return 0;