Adapt PEM routines to the opaque EVP_ENCODE_CTX
authorRichard Levitte <levitte@openssl.org>
Fri, 11 Dec 2015 15:10:38 +0000 (16:10 +0100)
committerRichard Levitte <levitte@openssl.org>
Fri, 11 Dec 2015 15:18:01 +0000 (16:18 +0100)
Reviewed-by: Rich Salz <rsalz@openssl.org>
crypto/pem/pem_lib.c
crypto/pem/pem_seal.c
include/openssl/pem.h

index 23b347ff5e7af8384f1b59c7dcd78a719e8ec40d..42a8583fb184234e0c3212faeb68ed299b1ec5aa 100644 (file)
@@ -600,10 +600,15 @@ int PEM_write_bio(BIO *bp, const char *name, const char *header,
 {
     int nlen, n, i, j, outl;
     unsigned char *buf = NULL;
-    EVP_ENCODE_CTX ctx;
+    EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
     int reason = ERR_R_BUF_LIB;
 
-    EVP_EncodeInit(&ctx);
+    if (ctx == NULL) {
+        reason = ERR_R_MALLOC_FAILURE;
+        goto err;
+    }
+
+    EVP_EncodeInit(ctx);
     nlen = strlen(name);
 
     if ((BIO_write(bp, "-----BEGIN ", 11) != 11) ||
@@ -626,25 +631,26 @@ int PEM_write_bio(BIO *bp, const char *name, const char *header,
     i = j = 0;
     while (len > 0) {
         n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len);
-        EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n);
+        EVP_EncodeUpdate(ctx, buf, &outl, &(data[j]), n);
         if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl))
             goto err;
         i += outl;
         len -= n;
         j += n;
     }
-    EVP_EncodeFinal(&ctx, buf, &outl);
+    EVP_EncodeFinal(ctx, buf, &outl);
     if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl))
         goto err;
-    OPENSSL_clear_free(buf, PEM_BUFSIZE * 8);
-    buf = NULL;
     if ((BIO_write(bp, "-----END ", 9) != 9) ||
         (BIO_write(bp, name, nlen) != nlen) ||
         (BIO_write(bp, "-----\n", 6) != 6))
         goto err;
+    OPENSSL_clear_free(buf, PEM_BUFSIZE * 8);
+    EVP_ENCODE_CTX_free(ctx);
     return (i + outl);
  err:
     OPENSSL_clear_free(buf, PEM_BUFSIZE * 8);
+    EVP_ENCODE_CTX_free(ctx);
     PEMerr(PEM_F_PEM_WRITE_BIO, reason);
     return (0);
 }
@@ -670,22 +676,23 @@ int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,
 int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
                  long *len)
 {
-    EVP_ENCODE_CTX ctx;
+    EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
     int end = 0, i, k, bl = 0, hl = 0, nohead = 0;
     char buf[256];
     BUF_MEM *nameB;
     BUF_MEM *headerB;
     BUF_MEM *dataB, *tmpB;
 
+    if (ctx == NULL) {
+        PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+
     nameB = BUF_MEM_new();
     headerB = BUF_MEM_new();
     dataB = BUF_MEM_new();
     if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) {
-        BUF_MEM_free(nameB);
-        BUF_MEM_free(headerB);
-        BUF_MEM_free(dataB);
-        PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
-        return (0);
+        goto err;
     }
 
     buf[254] = '\0';
@@ -805,15 +812,15 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
         goto err;
     }
 
-    EVP_DecodeInit(&ctx);
-    i = EVP_DecodeUpdate(&ctx,
+    EVP_DecodeInit(ctx);
+    i = EVP_DecodeUpdate(ctx,
                          (unsigned char *)dataB->data, &bl,
                          (unsigned char *)dataB->data, bl);
     if (i < 0) {
         PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE);
         goto err;
     }
-    i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k);
+    i = EVP_DecodeFinal(ctx, (unsigned char *)&(dataB->data[bl]), &k);
     if (i < 0) {
         PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE);
         goto err;
@@ -829,11 +836,13 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
     OPENSSL_free(nameB);
     OPENSSL_free(headerB);
     OPENSSL_free(dataB);
+    EVP_ENCODE_CTX_free(ctx);
     return (1);
  err:
     BUF_MEM_free(nameB);
     BUF_MEM_free(headerB);
     BUF_MEM_free(dataB);
+    EVP_ENCODE_CTX_free(ctx);
     return (0);
 }
 
index d0db77783219ed3a9bf25b49707fcccee8183f73..f7c9e3f8186bed167115a20c3a771bd3006741f4 100644 (file)
@@ -91,7 +91,8 @@ int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
         goto err;
     }
 
-    EVP_EncodeInit(&ctx->encode);
+    ctx->encode = EVP_ENCODE_CTX_new();
+    EVP_EncodeInit(ctx->encode);
 
     ctx->md = EVP_MD_CTX_new();
     if (!EVP_SignInit(ctx->md, md_type))
@@ -135,7 +136,7 @@ int PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
             i = inl;
         if (!EVP_EncryptUpdate(&ctx->cipher, buffer, &j, in, i))
             return 0;
-        EVP_EncodeUpdate(&ctx->encode, out, &j, buffer, j);
+        EVP_EncodeUpdate(ctx->encode, out, &j, buffer, j);
         *outl += j;
         out += j;
         in += i;
@@ -166,10 +167,10 @@ int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
 
     if (!EVP_EncryptFinal_ex(&ctx->cipher, s, (int *)&i))
         goto err;
-    EVP_EncodeUpdate(&ctx->encode, out, &j, s, i);
+    EVP_EncodeUpdate(ctx->encode, out, &j, s, i);
     *outl = j;
     out += j;
-    EVP_EncodeFinal(&ctx->encode, out, &j);
+    EVP_EncodeFinal(ctx->encode, out, &j);
     *outl += j;
 
     if (!EVP_SignFinal(ctx->md, s, &i, priv))
@@ -178,6 +179,7 @@ int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
 
     ret = 1;
  err:
+    EVP_ENCODE_CTX_free(ctx->encode);
     EVP_MD_CTX_free(ctx->md);
     EVP_CIPHER_CTX_cleanup(&ctx->cipher);
     OPENSSL_free(s);
index 2746e0eb2e6721ef25607ca3e9ea6c14c96e9e7c..fe2cf11f1460150cf6bc762b09d6c98af0a90bbf 100644 (file)
@@ -103,7 +103,7 @@ extern "C" {
    * by PEM_SealFinal (at least for now)
    */
 typedef struct PEM_Encode_Seal_st {
-    EVP_ENCODE_CTX encode;
+    EVP_ENCODE_CTX *encode;
     EVP_MD_CTX *md;
     EVP_CIPHER_CTX cipher;
 } PEM_ENCODE_SEAL_CTX;