1 | /* |
2 | * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. |
3 | * |
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at |
7 | * https://www.openssl.org/source/license.html |
8 | */ |
9 | |
10 | /* |
11 | * TODO(v3.0): the IMPLEMENT macros in include/openssl/pem.h should be |
12 | * moved here. |
13 | */ |
14 | |
15 | #include <openssl/pem.h> |
16 | #include <openssl/serializer.h> |
17 | |
18 | /* Alternative IMPLEMENT macros for provided serializers */ |
19 | |
20 | # define IMPLEMENT_PEM_provided_write_body_vars(type, asn1) \ |
21 | int ret = 0; \ |
22 | const char *pq = OSSL_SERIALIZER_##asn1##_TO_PEM_PQ; \ |
23 | OSSL_SERIALIZER_CTX *ctx = OSSL_SERIALIZER_CTX_new_by_##type(x, pq); \ |
24 | \ |
25 | if (ctx != NULL && OSSL_SERIALIZER_CTX_get_serializer(ctx) == NULL) { \ |
26 | OSSL_SERIALIZER_CTX_free(ctx); \ |
27 | goto legacy; \ |
28 | } |
29 | # define IMPLEMENT_PEM_provided_write_body_pass() \ |
30 | ret = 1; \ |
31 | if (kstr == NULL && cb == NULL) { \ |
32 | if (u != NULL) { \ |
33 | kstr = u; \ |
34 | klen = strlen(u); \ |
35 | } else { \ |
36 | cb = PEM_def_callback; \ |
37 | } \ |
38 | } \ |
39 | if (enc != NULL) { \ |
40 | ret = 0; \ |
41 | if (OSSL_SERIALIZER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc), \ |
42 | NULL)) { \ |
43 | ret = 1; \ |
44 | if (kstr != NULL \ |
45 | && !OSSL_SERIALIZER_CTX_set_passphrase(ctx, kstr, klen)) \ |
46 | ret = 0; \ |
47 | else if (cb != NULL \ |
48 | && !OSSL_SERIALIZER_CTX_set_passphrase_cb(ctx, 1, \ |
49 | cb, u)) \ |
50 | ret = 0; \ |
51 | } \ |
52 | } \ |
53 | if (!ret) { \ |
54 | OSSL_SERIALIZER_CTX_free(ctx); \ |
55 | return 0; \ |
56 | } |
57 | # define IMPLEMENT_PEM_provided_write_body_main(type, outtype) \ |
58 | ret = OSSL_SERIALIZER_to_##outtype(ctx, out); \ |
59 | OSSL_SERIALIZER_CTX_free(ctx); \ |
60 | return ret |
61 | # define IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \ |
62 | writename) \ |
63 | legacy: \ |
64 | return PEM_ASN1_##writename((i2d_of_void *)i2d_##asn1, str, out, \ |
65 | x, NULL, NULL, 0, NULL, NULL) |
66 | # define IMPLEMENT_PEM_provided_write_body_fallback_cb(str, asn1, \ |
67 | writename) \ |
68 | legacy: \ |
69 | return PEM_ASN1_##writename((i2d_of_void *)i2d_##asn1, str, out, \ |
70 | x, enc, kstr, klen, cb, u) |
71 | |
72 | # define IMPLEMENT_PEM_provided_write_to(name, type, str, asn1, \ |
73 | OUTTYPE, outtype, writename) \ |
74 | PEM_write_fnsig(name, type, OUTTYPE, writename) \ |
75 | { \ |
76 | IMPLEMENT_PEM_provided_write_body_vars(type, asn1); \ |
77 | IMPLEMENT_PEM_provided_write_body_main(type, outtype); \ |
78 | IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \ |
79 | writename); \ |
80 | } |
81 | |
82 | |
83 | # define IMPLEMENT_PEM_provided_write_cb_to(name, type, str, asn1, \ |
84 | OUTTYPE, outtype, writename) \ |
85 | PEM_write_cb_fnsig(name, type, OUTTYPE, writename) \ |
86 | { \ |
87 | IMPLEMENT_PEM_provided_write_body_vars(type, asn1); \ |
88 | IMPLEMENT_PEM_provided_write_body_pass(); \ |
89 | IMPLEMENT_PEM_provided_write_body_main(type, outtype); \ |
90 | IMPLEMENT_PEM_provided_write_body_fallback_cb(str, asn1, \ |
91 | writename); \ |
92 | } |
93 | |
94 | # ifdef OPENSSL_NO_STDIO |
95 | |
96 | # define IMPLEMENT_PEM_provided_write_fp(name, type, str, asn1) |
97 | # define IMPLEMENT_PEM_provided_write_cb_fp(name, type, str, asn1) |
98 | |
99 | # else |
100 | |
101 | # define IMPLEMENT_PEM_provided_write_fp(name, type, str, asn1) \ |
102 | IMPLEMENT_PEM_provided_write_to(name, type, str, asn1, FILE, fp, write) |
103 | # define IMPLEMENT_PEM_provided_write_cb_fp(name, type, str, asn1) \ |
104 | IMPLEMENT_PEM_provided_write_cb_to(name, type, str, asn1, FILE, fp, write) |
105 | |
106 | # endif |
107 | |
108 | # define IMPLEMENT_PEM_provided_write_bio(name, type, str, asn1) \ |
109 | IMPLEMENT_PEM_provided_write_to(name, type, str, asn1, BIO, bio, write_bio) |
110 | # define IMPLEMENT_PEM_provided_write_cb_bio(name, type, str, asn1) \ |
111 | IMPLEMENT_PEM_provided_write_cb_to(name, type, str, asn1, BIO, bio, write_bio) |
112 | |
113 | # define IMPLEMENT_PEM_provided_write(name, type, str, asn1) \ |
114 | IMPLEMENT_PEM_provided_write_bio(name, type, str, asn1) \ |
115 | IMPLEMENT_PEM_provided_write_fp(name, type, str, asn1) |
116 | |
117 | # define IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1) \ |
118 | IMPLEMENT_PEM_provided_write_cb_bio(name, type, str, asn1) \ |
119 | IMPLEMENT_PEM_provided_write_cb_fp(name, type, str, asn1) |
120 | |
121 | # define IMPLEMENT_PEM_provided_rw(name, type, str, asn1) \ |
122 | IMPLEMENT_PEM_read(name, type, str, asn1) \ |
123 | IMPLEMENT_PEM_provided_write(name, type, str, asn1) |
124 | |
125 | # define IMPLEMENT_PEM_provided_rw_cb(name, type, str, asn1) \ |
126 | IMPLEMENT_PEM_read(name, type, str, asn1) \ |
127 | IMPLEMENT_PEM_provided_write_cb(name, type, str, asn1) |
128 | |
129 | |