engine: fix double free on error path.
[openssl.git] / engines / e_loader_attic.c
index 72ceb38a3396613150e434d49be2c3ef03345576..802b3d9067188355533a7a63c674f2887faf2204 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2021 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
@@ -31,9 +31,9 @@
 #include <openssl/engine.h>
 #include <openssl/x509.h>        /* For the PKCS8 stuff o.O */
 #include "internal/asn1.h"       /* For asn1_d2i_read_bio */
-#include "internal/pem.h"        /* For PVK and "blob" PEM headers */
 #include "internal/o_dir.h"
 #include "internal/cryptlib.h"
+#include "crypto/pem.h"          /* For PVK and "blob" PEM headers */
 
 #include "e_loader_attic_err.c"
 
@@ -322,12 +322,13 @@ static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name,
 
             *matchcount = 1;
 
-            if (PKCS12_verify_mac(p12, "", 0)
+            if (!PKCS12_mac_present(p12)
+                || PKCS12_verify_mac(p12, "", 0)
                 || PKCS12_verify_mac(p12, NULL, 0)) {
                 pass = "";
             } else {
                 if ((pass = file_get_pass(ui_method, tpass, PEM_BUFSIZE,
-                                          "PKCS12 import pass phrase", uri,
+                                          "PKCS12 import", uri,
                                           ui_data)) == NULL) {
                     ATTICerr(0, ATTIC_R_PASSPHRASE_CALLBACK_ERROR);
                     goto p12_end;
@@ -478,6 +479,7 @@ static OSSL_STORE_INFO *try_decode_PKCS8Encrypted(const char *pem_name,
     mem->data = (char *)new_data;
     mem->max = mem->length = (size_t)new_data_len;
     X509_SIG_free(p8);
+    p8 = NULL;
 
     store_info = new_EMBEDDED(PEM_STRING_PKCS8INF, mem);
     if (store_info == NULL) {
@@ -1154,7 +1156,8 @@ static int file_find(OSSL_STORE_LOADER_CTX *ctx,
             return 0;
         }
 
-        hash = X509_NAME_hash(OSSL_STORE_SEARCH_get0_name(search));
+        hash = X509_NAME_hash_ex(OSSL_STORE_SEARCH_get0_name(search),
+                                 NULL, NULL, NULL);
         BIO_snprintf(ctx->_.dir.search_name, sizeof(ctx->_.dir.search_name),
                      "%08lx", hash);
         return 1;
@@ -1232,10 +1235,13 @@ static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx,
                 }
                 if (result == NULL)
                     result = tmp_result;
+                if (result == NULL) /* e.g., PKCS#12 file decryption error */
+                    break;
             }
         }
 
-        if (*matchcount == 1 && matching_handlers[0]->repeatable) {
+        if (result != NULL
+                && *matchcount == 1 && matching_handlers[0]->repeatable) {
             ctx->_.file.last_handler = matching_handlers[0];
             ctx->_.file.last_handler_ctx = handler_ctx;
         }
@@ -1334,9 +1340,6 @@ static int file_read_pem(BIO *bp, char **pem_name, char **pem_header,
 
 static OSSL_STORE_INFO *file_try_read_msblob(BIO *bp, int *matchcount)
 {
-#ifdef OPENSSL_NO_DSA
-    return NULL;
-#else
     OSSL_STORE_INFO *result = NULL;
     int ispub = -1;
 
@@ -1368,16 +1371,12 @@ static OSSL_STORE_INFO *file_try_read_msblob(BIO *bp, int *matchcount)
     }
 
     return result;
-#endif
 }
 
 static OSSL_STORE_INFO *file_try_read_PVK(BIO *bp, const UI_METHOD *ui_method,
                                           void *ui_data, const char *uri,
                                           int *matchcount)
 {
-#if defined(OPENSSL_NO_DSA) || defined(OPENSSL_NO_RC4)
-    return NULL;
-#else
     OSSL_STORE_INFO *result = NULL;
 
     {
@@ -1407,7 +1406,6 @@ static OSSL_STORE_INFO *file_try_read_PVK(BIO *bp, const UI_METHOD *ui_method,
     }
 
     return result;
-#endif
 }
 
 static int file_read_asn1(BIO *bp, unsigned char **data, long *len)
@@ -1424,27 +1422,13 @@ static int file_read_asn1(BIO *bp, unsigned char **data, long *len)
     return 1;
 }
 
-static int ends_with_dirsep(const char *uri)
-{
-    if (*uri != '\0')
-        uri += strlen(uri) - 1;
-#if defined(__VMS)
-    if (*uri == ']' || *uri == '>' || *uri == ':')
-        return 1;
-#elif defined(_WIN32)
-    if (*uri == '\\')
-        return 1;
-#endif
-    return *uri == '/';
-}
-
 static int file_name_to_uri(OSSL_STORE_LOADER_CTX *ctx, const char *name,
                             char **data)
 {
     assert(name != NULL);
     assert(data != NULL);
     {
-        const char *pathsep = ends_with_dirsep(ctx->uri) ? "" : "/";
+        const char *pathsep = ossl_ends_with_dirsep(ctx->uri) ? "" : "/";
         long calculated_length = strlen(ctx->uri) + strlen(pathsep)
             + strlen(name) + 1 /* \0 */;