transparently handle X9.42 DH parameters
[openssl.git] / crypto / pem / pvkfmt.c
index 5d391cfd8ef8bc15491b0c4d1588d802c21f3f23..b1bf71a5daad4ce62e8365d167bde8ad5a4f37d0 100644 (file)
@@ -63,6 +63,7 @@
 #include <openssl/pem.h>
 #include <openssl/rand.h>
 #include <openssl/bn.h>
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
 #include <openssl/dsa.h>
 #include <openssl/rsa.h>
 
@@ -653,13 +654,15 @@ int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk)
        return do_i2b_bio(out, pk, 1);
        }
 
+#ifndef OPENSSL_NO_RC4
+
 static int do_PVK_header(const unsigned char **in, unsigned int length,
                int skip_magic,
                unsigned int *psaltlen, unsigned int *pkeylen)
                
        {
        const unsigned char *p = *in;
-       unsigned int pvk_magic, keytype, is_encrypted;
+       unsigned int pvk_magic, is_encrypted;
        if (skip_magic)
                {
                if (length < 20)
@@ -686,7 +689,7 @@ static int do_PVK_header(const unsigned char **in, unsigned int length,
                }
        /* Skip reserved */
        p += 4;
-       keytype = read_ledword(&p);
+       /*keytype = */read_ledword(&p);
        is_encrypted = read_ledword(&p);
        *psaltlen = read_ledword(&p);
        *pkeylen = read_ledword(&p);
@@ -706,13 +709,16 @@ static int derive_pvk_key(unsigned char *key,
                        const unsigned char *pass, int passlen)
        {
        EVP_MD_CTX mctx;
+       int rv = 1;
        EVP_MD_CTX_init(&mctx);
-       EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL);
-       EVP_DigestUpdate(&mctx, salt, saltlen);
-       EVP_DigestUpdate(&mctx, pass, passlen);
-       EVP_DigestFinal_ex(&mctx, key, NULL);
+       if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL)
+               || !EVP_DigestUpdate(&mctx, salt, saltlen)
+               || !EVP_DigestUpdate(&mctx, pass, passlen)
+               || !EVP_DigestFinal_ex(&mctx, key, NULL))
+                       rv = 0;
+
        EVP_MD_CTX_cleanup(&mctx);
-       return 1;
+       return rv;
        }
        
 
@@ -724,11 +730,12 @@ static EVP_PKEY *do_PVK_body(const unsigned char **in,
        const unsigned char *p = *in;
        unsigned int magic;
        unsigned char *enctmp = NULL, *q;
+       EVP_CIPHER_CTX cctx;
+       EVP_CIPHER_CTX_init(&cctx);
        if (saltlen)
                {
                char psbuf[PEM_BUFSIZE];
                unsigned char keybuf[20];
-               EVP_CIPHER_CTX cctx;
                int enctmplen, inlen;
                if (cb)
                        inlen=cb(psbuf,PEM_BUFSIZE,0,u);
@@ -754,37 +761,41 @@ static EVP_PKEY *do_PVK_body(const unsigned char **in,
                p += 8;
                inlen = keylen - 8;
                q = enctmp + 8;
-               EVP_CIPHER_CTX_init(&cctx);
-               EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL);
-               EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen);
-               EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen);
+               if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
+                       goto err;
+               if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
+                       goto err;
+               if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen))
+                       goto err;
                magic = read_ledword((const unsigned char **)&q);
                if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
                        {
                        q = enctmp + 8;
                        memset(keybuf + 5, 0, 11);
-                       EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf,
-                                                               NULL);
+                       if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf,
+                                                               NULL))
+                               goto err;
                        OPENSSL_cleanse(keybuf, 20);
-                       EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen);
-                       EVP_DecryptFinal_ex(&cctx, q + enctmplen,
-                                                               &enctmplen);
+                       if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
+                               goto err;
+                       if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen,
+                                                               &enctmplen))
+                               goto err;
                        magic = read_ledword((const unsigned char **)&q);
                        if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC)
                                {
-                               EVP_CIPHER_CTX_cleanup(&cctx);
                                PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
                                goto err;
                                }
                        }
                else
                        OPENSSL_cleanse(keybuf, 20);
-               EVP_CIPHER_CTX_cleanup(&cctx);
                p = enctmp;
                }
 
        ret = b2i_PrivateKey(&p, keylen);
        err:
+       EVP_CIPHER_CTX_cleanup(&cctx);
        if (enctmp && saltlen)
                OPENSSL_free(enctmp);
        return ret;
@@ -836,8 +847,10 @@ EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
 static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel,
                pem_password_cb *cb, void *u)
        {
-       int outlen = 24, noinc, pklen;
+       int outlen = 24, pklen;
        unsigned char *p, *salt = NULL;
+       EVP_CIPHER_CTX cctx;
+       EVP_CIPHER_CTX_init(&cctx);
        if (enclevel)
                outlen += PVK_SALTLEN;
        pklen = do_i2b(NULL, pk, 0);
@@ -847,10 +860,7 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel,
        if (!out)
                return outlen;
        if (*out)
-               {
                p = *out;
-               noinc = 0;
-               }
        else
                {
                p = OPENSSL_malloc(outlen);
@@ -860,7 +870,6 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel,
                        return -1;
                        }
                *out = p;
-               noinc = 1;
                }
 
        write_ledword(&p, MS_PVKMAGIC);
@@ -886,7 +895,6 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel,
                {
                char psbuf[PEM_BUFSIZE];
                unsigned char keybuf[20];
-               EVP_CIPHER_CTX cctx;
                int enctmplen, inlen;
                if (cb)
                        inlen=cb(psbuf,PEM_BUFSIZE,1,u);
@@ -903,16 +911,19 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel,
                if (enclevel == 1)
                        memset(keybuf + 5, 0, 11);
                p = salt + PVK_SALTLEN + 8;
-               EVP_CIPHER_CTX_init(&cctx);
-               EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL);
+               if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
+                       goto error;
                OPENSSL_cleanse(keybuf, 20);
-               EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8);
-               EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen);
-               EVP_CIPHER_CTX_cleanup(&cctx);
+               if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8))
+                       goto error;
+               if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen))
+                       goto error;
                }
+       EVP_CIPHER_CTX_cleanup(&cctx);
        return outlen;
 
        error:
+       EVP_CIPHER_CTX_cleanup(&cctx);
        return -1;
        }
 
@@ -933,3 +944,7 @@ int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
                }
        return -1;
        }
+
+#endif
+
+#endif