STORE: Add a OSSL_STORE_INFO type to help support file handler restarts
authorRichard Levitte <levitte@openssl.org>
Thu, 8 Dec 2016 13:28:42 +0000 (14:28 +0100)
committerRichard Levitte <levitte@openssl.org>
Thu, 29 Jun 2017 09:55:31 +0000 (11:55 +0200)
Some containers might very simply decode into something new that
deserves to be considered as new (embedded) data.  With the help of a
special OSSL_STORE_INFO type, make that new data available to the
loader functions so they can start over.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3542)

crypto/err/openssl.txt
crypto/store/store_err.c
crypto/store/store_lib.c
crypto/store/store_locl.h
include/openssl/storeerr.h

index e03432c..5efa37e 100644 (file)
@@ -737,6 +737,7 @@ OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS:104:OSSL_STORE_INFO_get1_PARAMS
 OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY:105:OSSL_STORE_INFO_get1_PKEY
 OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT:106:OSSL_STORE_INFO_new_CERT
 OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL:107:OSSL_STORE_INFO_new_CRL
+OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED:123:ossl_store_info_new_EMBEDDED
 OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME:109:OSSL_STORE_INFO_new_NAME
 OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS:110:OSSL_STORE_INFO_new_PARAMS
 OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY:111:OSSL_STORE_INFO_new_PKEY
index ab8439c..0f3a6a1 100644 (file)
@@ -36,6 +36,8 @@ static const ERR_STRING_DATA OSSL_STORE_str_functs[] = {
      "OSSL_STORE_INFO_new_CERT"},
     {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL, 0),
      "OSSL_STORE_INFO_new_CRL"},
+    {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED, 0),
+     "ossl_store_info_new_EMBEDDED"},
     {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME, 0),
      "OSSL_STORE_INFO_new_NAME"},
     {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS, 0),
index 5f07f8c..2c8ce86 100644 (file)
@@ -343,6 +343,10 @@ void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info)
 {
     if (info != NULL) {
         switch (info->type) {
+        case OSSL_STORE_INFO_EMBEDDED:
+            BUF_MEM_free(info->_.embedded.blob);
+            OPENSSL_free(info->_.embedded.pem_name);
+            break;
         case OSSL_STORE_INFO_NAME:
             OPENSSL_free(info->_.name.name);
             OPENSSL_free(info->_.name.desc);
@@ -364,3 +368,42 @@ void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info)
     }
 }
 
+/* Internal functions */
+OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name,
+                                              BUF_MEM *embedded)
+{
+    OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_EMBEDDED, NULL);
+
+    if (info == NULL) {
+        OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED,
+                      ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    info->_.embedded.blob = embedded;
+    info->_.embedded.pem_name =
+        new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name);
+
+    if (new_pem_name != NULL && info->_.embedded.pem_name == NULL) {
+        OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED,
+                      ERR_R_MALLOC_FAILURE);
+        OSSL_STORE_INFO_free(info);
+        info = NULL;
+    }
+
+    return info;
+}
+
+BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info)
+{
+    if (info->type == OSSL_STORE_INFO_EMBEDDED)
+        return info->_.embedded.blob;
+    return NULL;
+}
+
+char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info)
+{
+    if (info->type == OSSL_STORE_INFO_EMBEDDED)
+        return info->_.embedded.pem_name;
+    return NULL;
+}
index cf14e53..5797a36 100644 (file)
 struct ossl_store_info_st {
     int type;
     union {
+        void *data;              /* used internally as generic pointer */
+
+        struct {
+            BUF_MEM *blob;
+            char *pem_name;
+        } embedded;              /* when type == OSSL_STORE_INFO_EMBEDDED */
+
         struct {
             char *name;
             char *desc;
@@ -32,12 +39,28 @@ struct ossl_store_info_st {
         EVP_PKEY *pkey;          /* when type == OSSL_STORE_INFO_PKEY */
         X509 *x509;              /* when type == OSSL_STORE_INFO_CERT */
         X509_CRL *crl;           /* when type == OSSL_STORE_INFO_CRL */
-        void *data;              /* used internally */
     } _;
 };
 
 DEFINE_STACK_OF(OSSL_STORE_INFO)
 
+/*
+ * EMBEDDED is a special type of OSSL_STORE_INFO, specially for the file
+ * handlers.  It should never reach a calling application or any engine.
+ * However, it can be used by a FILE_HANDLER's try_decode function to signal
+ * that it has decoded the incoming blob into a new blob, and that the
+ * attempted decoding should be immediately restarted with the new blob, using
+ * the new PEM name.
+ */
+/*
+ * Because this is an internal type, we don't make it public.
+ */
+#define OSSL_STORE_INFO_EMBEDDED       -1
+OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name,
+                                              BUF_MEM *embedded);
+BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info);
+char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info);
+
 /*-
  *  OSSL_STORE_LOADER stuff
  *  -----------------------
index 1458574..1d86955 100644 (file)
@@ -34,6 +34,7 @@ int ERR_load_OSSL_STORE_strings(void);
 # define OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY           105
 # define OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT            106
 # define OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL             107
+# define OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED        123
 # define OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME            109
 # define OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS          110
 # define OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY            111