Add support for RSA-PSS to X509_certificate_type()
[openssl.git] / crypto / pkcs12 / p12_key.c
index 4f1d29bb6d4996366024790ffda08a5bd1f3ef44..ab31a6129500ebc09dfedd8a15ac84cdccc338c2 100644 (file)
@@ -50,15 +50,37 @@ int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
     return ret;
 }
 
+int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt,
+                        int saltlen, int id, int iter, int n,
+                        unsigned char *out, const EVP_MD *md_type)
+{
+    int ret;
+    unsigned char *unipass;
+    int uniplen;
+
+    if (!pass) {
+        unipass = NULL;
+        uniplen = 0;
+    } else if (!OPENSSL_utf82uni(pass, passlen, &unipass, &uniplen)) {
+        PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UTF8, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
+                             id, iter, n, out, md_type);
+    if (ret <= 0)
+        return 0;
+    OPENSSL_clear_free(unipass, uniplen);
+    return ret;
+}
+
 int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
                        int saltlen, int id, int iter, int n,
                        unsigned char *out, const EVP_MD *md_type)
 {
     unsigned char *B = NULL, *D = NULL, *I = NULL, *p = NULL, *Ai = NULL;
-    int Slen, Plen, Ilen, Ijlen;
+    int Slen, Plen, Ilen;
     int i, j, u, v;
     int ret = 0;
-    BIGNUM *Ij = NULL, *Bpl1 = NULL; /* These hold Ij and B + 1 */
     EVP_MD_CTX *ctx = NULL;
 #ifdef  OPENSSL_DEBUG_KEYGEN
     unsigned char *tmpout = out;
@@ -91,10 +113,7 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
         Plen = 0;
     Ilen = Slen + Plen;
     I = OPENSSL_malloc(Ilen);
-    Ij = BN_new();
-    Bpl1 = BN_new();
-    if (D == NULL || Ai == NULL || B == NULL || I == NULL || Ij == NULL
-            || Bpl1 == NULL)
+    if (D == NULL || Ai == NULL || B == NULL || I == NULL)
         goto err;
     for (i = 0; i < v; i++)
         D[i] = id;
@@ -128,33 +147,17 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
         out += u;
         for (j = 0; j < v; j++)
             B[j] = Ai[j % u];
-        /* Work out B + 1 first then can use B as tmp space */
-        if (!BN_bin2bn(B, v, Bpl1))
-            goto err;
-        if (!BN_add_word(Bpl1, 1))
-            goto err;
         for (j = 0; j < Ilen; j += v) {
-            if (!BN_bin2bn(I + j, v, Ij))
-                goto err;
-            if (!BN_add(Ij, Ij, Bpl1))
-                goto err;
-            if (!BN_bn2bin(Ij, B))
-                goto err;
-            Ijlen = BN_num_bytes(Ij);
-            /* If more than 2^(v*8) - 1 cut off MSB */
-            if (Ijlen > v) {
-                if (!BN_bn2bin(Ij, B))
-                    goto err;
-                memcpy(I + j, B + 1, v);
-#ifndef PKCS12_BROKEN_KEYGEN
-                /* If less than v bytes pad with zeroes */
-            } else if (Ijlen < v) {
-                memset(I + j, 0, v - Ijlen);
-                if (!BN_bn2bin(Ij, I + j + v - Ijlen))
-                    goto err;
-#endif
-            } else if (!BN_bn2bin(Ij, I + j))
-                goto err;
+            int k;
+            unsigned char *Ij = I + j;
+            uint16_t c = 1;
+
+            /* Work out Ij = Ij + B + 1 */
+            for (k = v - 1; k >= 0; k--) {
+                c += Ij[k] + B[k];
+                Ij[k] = (unsigned char)c;
+                c >>= 8;
+            }
         }
     }
 
@@ -166,8 +169,6 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
     OPENSSL_free(B);
     OPENSSL_free(D);
     OPENSSL_free(I);
-    BN_free(Ij);
-    BN_free(Bpl1);
     EVP_MD_CTX_free(ctx);
     return ret;
 }