summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2019-11-18 01:44:23 +0100
committerRichard Levitte <levitte@openssl.org>2019-11-29 20:55:16 +0100
commitf864a9396a690958d26c87827ba6f26e7b010caf (patch)
treeeaefc07122a5280e455a1f93d4dcee66de402a35
parent866234ac35e665f20c646059b1d92c5e9eb0c7ab (diff)
SERIALIZER: add hooks in PEM_write_bio_ and PEM_write_fp_ routines
Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/10394)
-rw-r--r--crypto/pem/pem_all.c4
-rw-r--r--crypto/pem/pem_local.h128
-rw-r--r--crypto/pem/pem_pkey.c26
-rw-r--r--include/openssl/pem.h56
4 files changed, 175 insertions, 39 deletions
diff --git a/crypto/pem/pem_all.c b/crypto/pem/pem_all.c
index 975e62e9f7..2e8eb2e183 100644
--- a/crypto/pem/pem_all.c
+++ b/crypto/pem/pem_all.c
@@ -17,6 +17,7 @@
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/dh.h>
+#include "pem_local.h"
#ifndef OPENSSL_NO_RSA
static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa);
@@ -172,4 +173,5 @@ EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
IMPLEMENT_PEM_write(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
IMPLEMENT_PEM_write(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams)
#endif
-IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
+IMPLEMENT_PEM_provided_write(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
+IMPLEMENT_PEM_read(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
diff --git a/crypto/pem/pem_local.h b/crypto/pem/pem_local.h
new file mode 100644
index 0000000000..3b501abde7
--- /dev/null
+++ b/crypto/pem/pem_local.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2019 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * TODO(v3.0): the IMPLEMENT macros in include/openssl/pem.h should be
+ * moved here.
+ */
+
+#include <openssl/pem.h>
+#include <openssl/serializer.h>
+
+/* Alternative IMPLEMENT macros for provided serializers */
+
+# define IMPLEMENT_PEM_provided_write_body_vars(type, asn1) \
+ int ret = 0; \
+ const char *pq = OSSL_SERIALIZER_##asn1##_TO_PEM_PQ; \
+ OSSL_SERIALIZER_CTX *ctx = OSSL_SERIALIZER_CTX_new_by_##type(x, pq); \
+ \
+ if (ctx != NULL && OSSL_SERIALIZER_CTX_get_serializer(ctx) == NULL) { \
+ OSSL_SERIALIZER_CTX_free(ctx); \
+ goto legacy; \
+ }
+# define IMPLEMENT_PEM_provided_write_body_pass() \
+ ret = 1; \
+ if (kstr == NULL && cb == NULL) { \
+ if (u != NULL) { \
+ kstr = u; \
+ klen = strlen(u); \
+ } else { \
+ cb = PEM_def_callback; \
+ } \
+ } \
+ if (enc != NULL) { \
+ ret = 0; \
+ if (OSSL_SERIALIZER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc), \
+ NULL)) { \
+ ret = 1; \
+ if (kstr != NULL \
+ && !OSSL_SERIALIZER_CTX_set_passphrase(ctx, kstr, klen)) \
+ ret = 0; \
+ else if (cb != NULL \
+ && !OSSL_SERIALIZER_CTX_set_passphrase_cb(ctx, 1, \
+ cb, u)) \
+ ret = 0; \
+ } \
+ } \
+ if (!ret) { \
+ OSSL_SERIALIZER_CTX_free(ctx); \
+ return 0; \
+ }
+# define IMPLEMENT_PEM_provided_write_body_main(type, outtype) \
+ ret = OSSL_SERIALIZER_to_##outtype(ctx, out); \
+ OSSL_SERIALIZER_CTX_free(ctx); \
+ return ret
+# define IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \
+ writename) \
+ legacy: \
+ return PEM_ASN1_##writename((i2d_of_void *)i2d_##asn1, str, out, \
+ x, NULL, NULL, 0, NULL, NULL)
+# define IMPLEMENT_PEM_provided_write_body_fallback_cb(str, asn1, \
+ writename) \
+ legacy: \
+ return PEM_ASN1_##writename((i2d_of_void *)i2d_##asn1, str, out, \
+ x, enc, kstr, klen, cb, u)
+
+# define IMPLEMENT_PEM_provided_write_to(name, type, str, asn1, \
+ OUTTYPE, outtype, writename) \
+ PEM_write_fnsig(name, type, OUTTYPE, writename) \
+ { \
+ IMPLEMENT_PEM_provided_write_body_vars(type, asn1); \
+ IMPLEMENT_PEM_provided_write_body_main(type, outtype); \
+ IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \
+ writename); \
+ }
+
+
+# define IMPLEMENT_PEM_provided_write_cb_to(name, type, str, asn1, \
+ OUTTYPE, outtype, writename) \
+ PEM_write_cb_fnsig(name, type, OUTTYPE, writename) \
+ { \
+ IMPLEMENT_PEM_provided_write_body_vars(type, asn1); \
+ IMPLEMENT_PEM_provided_write_body_pass(); \
+ IMPLEMENT_PEM_provided_write_body_main(type, outtype); \
+ IMPLEMENT_PEM_provided_write_body_fallback_cb(str, asn1, \
+ writename); \
+ }
+
+# ifdef OPENSSL_NO_STDIO
+
+# define IMPLEMENT_PEM_provided_write_fp(name, type, str, asn1)
+# define IMPLEMENT_PEM_provided_write_cb_fp(name, type, str, asn1)
+
+# else
+
+# define IMPLEMENT_PEM_provided_write_fp(name, type, str, asn1) \
+ IMPLEMENT_PEM_provided_write_to(name, type, str, asn1, FILE, fp, write)
+# define IMPLEMENT_PEM_provided_write_cb_fp(name, type, str, asn1) \
+ IMPLEMENT_PEM_provided_write_cb_to(name, type, str, asn1, FILE, fp, write)
+
+# endif
+
+# define IMPLEMENT_PEM_provided_write_bio(name, type, str, asn1) \
+ IMPLEMENT_PEM_provided_write_to(name, type, str, asn1, BIO, bio, write_bio)
+# define IMPLEMENT_PEM_provided_write_cb_bio(name, type, str, asn1) \
+ IMPLEMENT_PEM_provided_write_cb_to(name, type, str, asn1, BIO, bio, write_bio)
+
+# define IMPLEMENT_PEM_provided_write(name, type, str, asn1) \
+ IMPLEMENT_PEM_provided_write_bio(name, type, str, asn1) \
+ IMPLEMENT_PEM_provided_write_fp(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1) \
+ IMPLEMENT_PEM_provided_write_cb_bio(name, type, str, asn1) \
+ IMPLEMENT_PEM_provided_write_cb_fp(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_provided_rw(name, type, str, asn1) \
+ IMPLEMENT_PEM_read(name, type, str, asn1) \
+ IMPLEMENT_PEM_provided_write(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_provided_rw_cb(name, type, str, asn1) \
+ IMPLEMENT_PEM_read(name, type, str, asn1) \
+ IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1)
+
diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c
index 6f89759f1e..c619cc11b4 100644
--- a/crypto/pem/pem_pkey.c
+++ b/crypto/pem/pem_pkey.c
@@ -19,9 +19,11 @@
#include <openssl/dh.h>
#include <openssl/store.h>
#include <openssl/ui.h>
+#include <openssl/serializer.h>
#include "crypto/store.h"
#include "crypto/asn1.h"
#include "crypto/evp.h"
+#include "pem_local.h"
int pem_check_suffix(const char *pem_str, const char *suffix);
@@ -64,15 +66,18 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
return ret;
}
-int PEM_write_bio_PrivateKey(BIO *bp, const EVP_PKEY *x,
- const EVP_CIPHER *enc,
- const unsigned char *kstr, int klen,
- pem_password_cb *cb, void *u)
+PEM_write_cb_fnsig(PrivateKey, EVP_PKEY, BIO, write_bio)
{
+ IMPLEMENT_PEM_provided_write_body_vars(EVP_PKEY, PrivateKey);
+
+ IMPLEMENT_PEM_provided_write_body_pass();
+ IMPLEMENT_PEM_provided_write_body_main(EVP_PKEY, bio);
+
+ legacy:
if (x->ameth == NULL || x->ameth->priv_encode != NULL)
- return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
+ return PEM_write_bio_PKCS8PrivateKey(out, x, enc,
(const char *)kstr, klen, cb, u);
- return PEM_write_bio_PrivateKey_traditional(bp, x, enc, kstr, klen, cb, u);
+ return PEM_write_bio_PrivateKey_traditional(out, x, enc, kstr, klen, cb, u);
}
int PEM_write_bio_PrivateKey_traditional(BIO *bp, const EVP_PKEY *x,
@@ -112,15 +117,20 @@ EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
return ret;
}
-int PEM_write_bio_Parameters(BIO *bp, const EVP_PKEY *x)
+PEM_write_fnsig(Parameters, EVP_PKEY, BIO, write_bio)
{
char pem_str[80];
+ IMPLEMENT_PEM_provided_write_body_vars(EVP_PKEY, Parameters);
+
+ IMPLEMENT_PEM_provided_write_body_main(EVP_PKEY, bio);
+
+ legacy:
if (!x->ameth || !x->ameth->param_encode)
return 0;
BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str);
return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode,
- pem_str, bp, x, NULL, NULL, 0, 0, NULL);
+ pem_str, out, x, NULL, NULL, 0, 0, NULL);
}
#ifndef OPENSSL_NO_STDIO
diff --git a/include/openssl/pem.h b/include/openssl/pem.h
index 35d01544ba..c90bec8eac 100644
--- a/include/openssl/pem.h
+++ b/include/openssl/pem.h
@@ -66,6 +66,14 @@ extern "C" {
* IMPLEMENT_PEM_rw_cb(...)
*/
+# define PEM_write_fnsig(name, type, OUTTYPE, writename) \
+ int PEM_##writename##_##name(OUTTYPE *out, const type *x)
+# define PEM_write_cb_fnsig(name, type, OUTTYPE, writename) \
+ int PEM_##writename##_##name(OUTTYPE *out, const type *x, \
+ const EVP_CIPHER *enc, \
+ const unsigned char *kstr, int klen, \
+ pem_password_cb *cb, void *u)
+
# ifdef OPENSSL_NO_STDIO
# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/
@@ -87,9 +95,9 @@ extern "C" {
}
# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
- int PEM_write_##name(FILE *fp, const type *x) \
+ PEM_write_fnsig(name, type, FILE, write) \
{ \
- return PEM_ASN1_write((i2d_of_void *)i2d_##asn1, str, fp, \
+ return PEM_ASN1_write((i2d_of_void *)i2d_##asn1, str, out, \
x, NULL, NULL, 0, NULL, NULL); \
}
@@ -99,12 +107,9 @@ extern "C" {
# endif
# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
- int PEM_write_##name(FILE *fp, const type *x, \
- const EVP_CIPHER *enc, \
- const unsigned char *kstr, int klen, \
- pem_password_cb *cb, void *u) \
+ PEM_write_cb_fnsig(name, type, FILE, write) \
{ \
- return PEM_ASN1_write((i2d_of_void *)i2d_##asn1, str, fp, \
+ return PEM_ASN1_write((i2d_of_void *)i2d_##asn1, str, out, \
x, enc, kstr, klen, cb, u); \
}
@@ -123,9 +128,9 @@ extern "C" {
}
# define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
- int PEM_write_bio_##name(BIO *bp, const type *x) \
+ PEM_write_fnsig(name, type, BIO, write_bio) \
{ \
- return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1, str, bp, \
+ return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1, str, out, \
x, NULL,NULL,0,NULL,NULL); \
}
@@ -135,12 +140,9 @@ extern "C" {
# endif
# define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
- int PEM_write_bio_##name(BIO *bp, const type *x, \
- const EVP_CIPHER *enc, \
- const unsigned char *kstr, int klen, \
- pem_password_cb *cb, void *u) \
+ PEM_write_cb_fnsig(name, type, BIO, write_bio) \
{ \
- return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1, str, bp, \
+ return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1, str, out, \
x, enc, kstr, klen, cb, u); \
}
@@ -203,18 +205,15 @@ extern "C" {
type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u);
# define DECLARE_PEM_write_fp(name, type) \
- int PEM_write_##name(FILE *fp, const type *x);
+ PEM_write_fnsig(name, type, FILE, write);
# ifndef OPENSSL_NO_DEPRECATED_3_0
-# define DECLARE_PEM_write_fp_const(name, type) \
- DECLARE_PEM_write_fp(name, type)
+# define DECLARE_PEM_write_fp_const(name, type) \
+ PEM_write_fnsig(name, type, FILE, write);
# endif
-# define DECLARE_PEM_write_cb_fp(name, type) \
- int PEM_write_##name(FILE *fp, const type *x, \
- const EVP_CIPHER *enc, \
- const unsigned char *kstr, int klen, \
- pem_password_cb *cb, void *u);
+# define DECLARE_PEM_write_cb_fp(name, type) \
+ PEM_write_cb_fnsig(name, type, FILE, write);
# endif
@@ -223,18 +222,15 @@ extern "C" {
pem_password_cb *cb, void *u);
# define DECLARE_PEM_write_bio(name, type) \
- int PEM_write_bio_##name(BIO *bp, const type *x);
+ PEM_write_fnsig(name, type, BIO, write_bio);
# ifndef OPENSSL_NO_DEPRECATED_3_0
-# define DECLARE_PEM_write_bio_const(name, type) \
- DECLARE_PEM_write_bio(name, type)
+# define DECLARE_PEM_write_bio_const(name, type) \
+ PEM_write_fnsig(name, type, BIO, write_bio);
# endif
-# define DECLARE_PEM_write_cb_bio(name, type) \
- int PEM_write_bio_##name(BIO *bp, const type *x, \
- const EVP_CIPHER *enc, \
- const unsigned char *kstr, int klen, \
- pem_password_cb *cb, void *u);
+# define DECLARE_PEM_write_cb_bio(name, type) \
+ PEM_write_cb_fnsig(name, type, BIO, write_bio);
# define DECLARE_PEM_write(name, type) \
DECLARE_PEM_write_bio(name, type) \