OSSL_STORE: Make the 'file' scheme loader handle MSBLOB and PVK files
[openssl.git] / crypto / pem / pvkfmt.c
index 6bcde93d6cddb99bef353fe923b6665a9e620219..e2f570288086e0f58e5b34d4ade6075dd450e7ce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
  * and PRIVATEKEYBLOB).
  */
 
+/*
+ * DSA low level APIs are deprecated for public use, but still ok for
+ * internal use.
+ */
+#include "internal/deprecated.h"
+
 #include "internal/cryptlib.h"
 #include <openssl/pem.h>
+#include "internal/pem_int.h"
 #include <openssl/rand.h>
 #include <openssl/bn.h>
 #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
@@ -83,9 +90,9 @@ static EVP_PKEY *b2i_rsa(const unsigned char **in,
 static EVP_PKEY *b2i_dss(const unsigned char **in,
                          unsigned int bitlen, int ispub);
 
-static int do_blob_header(const unsigned char **in, unsigned int length,
-                          unsigned int *pmagic, unsigned int *pbitlen,
-                          int *pisdss, int *pispub)
+int ossl_do_blob_header(const unsigned char **in, unsigned int length,
+                        unsigned int *pmagic, unsigned int *pbitlen,
+                        int *pisdss, int *pispub)
 {
     const unsigned char *p = *in;
     if (length < 16)
@@ -93,13 +100,13 @@ static int do_blob_header(const unsigned char **in, unsigned int length,
     /* bType */
     if (*p == MS_PUBLICKEYBLOB) {
         if (*pispub == 0) {
-            PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
+            PEMerr(PEM_F_OSSL_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
             return 0;
         }
         *pispub = 1;
     } else if (*p == MS_PRIVATEKEYBLOB) {
         if (*pispub == 1) {
-            PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
+            PEMerr(PEM_F_OSSL_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
             return 0;
         }
         *pispub = 0;
@@ -108,7 +115,7 @@ static int do_blob_header(const unsigned char **in, unsigned int length,
     p++;
     /* Version */
     if (*p++ != 0x2) {
-        PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER);
+        PEMerr(PEM_F_OSSL_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER);
         return 0;
     }
     /* Ignore reserved, aiKeyAlg */
@@ -123,7 +130,7 @@ static int do_blob_header(const unsigned char **in, unsigned int length,
         /* fall thru */
     case MS_RSA1MAGIC:
         if (*pispub == 0) {
-            PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
+            PEMerr(PEM_F_OSSL_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
             return 0;
         }
         break;
@@ -133,13 +140,13 @@ static int do_blob_header(const unsigned char **in, unsigned int length,
         /* fall thru */
     case MS_RSA2MAGIC:
         if (*pispub == 1) {
-            PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
+            PEMerr(PEM_F_OSSL_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
             return 0;
         }
         break;
 
     default:
-        PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER);
+        PEMerr(PEM_F_OSSL_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER);
         return -1;
     }
     *in = p;
@@ -185,7 +192,7 @@ static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length,
     const unsigned char *p = *in;
     unsigned int bitlen, magic;
     int isdss;
-    if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) {
+    if (ossl_do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) {
         PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
         return NULL;
     }
@@ -212,7 +219,7 @@ static EVP_PKEY *do_b2i_bio(BIO *in, int ispub)
         return NULL;
     }
     p = hdr_buf;
-    if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
+    if (ossl_do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
         return NULL;
 
     length = blob_length(bitlen, isdss, ispub);
@@ -424,7 +431,7 @@ static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic);
 static void write_rsa(unsigned char **out, RSA *rsa, int ispub);
 static void write_dsa(unsigned char **out, DSA *dsa, int ispub);
 
-static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub)
+static int do_i2b(unsigned char **out, const EVP_PKEY *pk, int ispub)
 {
     unsigned char *p;
     unsigned int bitlen, magic = 0, keyalg;
@@ -473,7 +480,7 @@ static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub)
     return outlen;
 }
 
-static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub)
+static int do_i2b_bio(BIO *out, const EVP_PKEY *pk, int ispub)
 {
     unsigned char *tmp = NULL;
     int outlen, wrlen;
@@ -599,38 +606,38 @@ static void write_dsa(unsigned char **out, DSA *dsa, int ispub)
     return;
 }
 
-int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk)
+int i2b_PrivateKey_bio(BIO *out, const EVP_PKEY *pk)
 {
     return do_i2b_bio(out, pk, 0);
 }
 
-int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk)
+int i2b_PublicKey_bio(BIO *out, const 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)
+int ossl_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, is_encrypted;
 
     if (skip_magic) {
         if (length < 20) {
-            PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+            PEMerr(PEM_F_OSSL_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
             return 0;
         }
     } else {
         if (length < 24) {
-            PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+            PEMerr(PEM_F_OSSL_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
             return 0;
         }
         pvk_magic = read_ledword(&p);
         if (pvk_magic != MS_PVKMAGIC) {
-            PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER);
+            PEMerr(PEM_F_OSSL_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER);
             return 0;
         }
     }
@@ -647,7 +654,7 @@ static int do_PVK_header(const unsigned char **in, unsigned int length,
         return 0;
 
     if (is_encrypted && *psaltlen == 0) {
-        PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER);
+        PEMerr(PEM_F_OSSL_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER);
         return 0;
     }
 
@@ -760,7 +767,7 @@ EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
     }
     p = pvk_hdr;
 
-    if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen))
+    if (!ossl_do_PVK_header(&p, 24, 0, &saltlen, &keylen))
         return 0;
     buflen = (int)keylen + saltlen;
     buf = OPENSSL_malloc(buflen);
@@ -780,7 +787,7 @@ EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
     return ret;
 }
 
-static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel,
+static int i2b_PVK(unsigned char **out, const EVP_PKEY *pk, int enclevel,
                    pem_password_cb *cb, void *u)
 {
     int outlen = 24, pklen;
@@ -865,7 +872,7 @@ static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel,
     return -1;
 }
 
-int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
+int i2b_PVK_bio(BIO *out, const EVP_PKEY *pk, int enclevel,
                 pem_password_cb *cb, void *u)
 {
     unsigned char *tmp = NULL;
@@ -876,9 +883,9 @@ int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
     wrlen = BIO_write(out, tmp, outlen);
     OPENSSL_free(tmp);
     if (wrlen == outlen) {
-        PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE);
         return outlen;
     }
+    PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE);
     return -1;
 }