]>
Commit | Line | Data |
---|---|---|
f864a939 | 1 | /* |
a28d06f3 | 2 | * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. |
f864a939 RL |
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 | ||
97bb8dff | 10 | #include <openssl/core_dispatch.h> |
f864a939 | 11 | #include <openssl/pem.h> |
ece9304c | 12 | #include <openssl/encoder.h> |
f864a939 | 13 | |
97bb8dff RL |
14 | /* |
15 | * Selectors, named according to the ASN.1 names used throughout libcrypto. | |
16 | * | |
17 | * Note that these are not absolutely mandatory, they are rather a wishlist | |
18 | * of sorts. The provider implementations are free to make choices that | |
19 | * make sense for them, based on these selectors. | |
20 | * For example, the EC backend is likely to really just output the private | |
21 | * key to a PKCS#8 structure, even thought PEM_SELECTION_PrivateKey specifies | |
22 | * the public key as well. This is fine, as long as the corresponding | |
23 | * decoding operation can return an object that contains what libcrypto | |
24 | * expects. | |
25 | */ | |
140eee2b RL |
26 | # define PEM_SELECTION_PUBKEY EVP_PKEY_PUBLIC_KEY |
27 | # define PEM_SELECTION_PrivateKey EVP_PKEY_KEYPAIR | |
28 | # define PEM_SELECTION_Parameters EVP_PKEY_KEY_PARAMETERS | |
97bb8dff | 29 | |
4227e504 RL |
30 | /* |
31 | * Properties, named according to the ASN.1 names used throughout libcrypto. | |
32 | */ | |
33 | # define PEM_STRUCTURE_PUBKEY "SubjectPublicKeyInfo" | |
34 | # define PEM_STRUCTURE_PrivateKey "pkcs8" | |
35 | # define PEM_STRUCTURE_Parameters "type-specific" | |
36 | ||
d7e498ac RL |
37 | # define PEM_STRUCTURE_RSAPrivateKey "type-specific" |
38 | # define PEM_STRUCTURE_RSAPublicKey "type-specific" | |
39 | ||
ece9304c | 40 | /* Alternative IMPLEMENT macros for provided encoders */ |
f864a939 | 41 | |
9256e8a2 | 42 | # define IMPLEMENT_PEM_provided_write_body_vars(type, asn1, pq) \ |
f864a939 | 43 | int ret = 0; \ |
97bb8dff | 44 | OSSL_ENCODER_CTX *ctx = \ |
fe75766c | 45 | OSSL_ENCODER_CTX_new_for_##type(x, PEM_SELECTION_##asn1, \ |
4227e504 | 46 | "PEM", PEM_STRUCTURE_##asn1, \ |
9256e8a2 | 47 | (pq)); \ |
f864a939 | 48 | \ |
97bb8dff | 49 | if (OSSL_ENCODER_CTX_get_num_encoders(ctx) == 0) { \ |
ece9304c | 50 | OSSL_ENCODER_CTX_free(ctx); \ |
f864a939 RL |
51 | goto legacy; \ |
52 | } | |
53 | # define IMPLEMENT_PEM_provided_write_body_pass() \ | |
54 | ret = 1; \ | |
55 | if (kstr == NULL && cb == NULL) { \ | |
56 | if (u != NULL) { \ | |
57 | kstr = u; \ | |
58 | klen = strlen(u); \ | |
59 | } else { \ | |
60 | cb = PEM_def_callback; \ | |
61 | } \ | |
62 | } \ | |
63 | if (enc != NULL) { \ | |
64 | ret = 0; \ | |
ece9304c RL |
65 | if (OSSL_ENCODER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc), \ |
66 | NULL)) { \ | |
f864a939 RL |
67 | ret = 1; \ |
68 | if (kstr != NULL \ | |
ece9304c | 69 | && !OSSL_ENCODER_CTX_set_passphrase(ctx, kstr, klen)) \ |
f864a939 RL |
70 | ret = 0; \ |
71 | else if (cb != NULL \ | |
97bb8dff RL |
72 | && !OSSL_ENCODER_CTX_set_pem_password_cb(ctx, \ |
73 | cb, u)) \ | |
f864a939 RL |
74 | ret = 0; \ |
75 | } \ | |
76 | } \ | |
77 | if (!ret) { \ | |
ece9304c | 78 | OSSL_ENCODER_CTX_free(ctx); \ |
f864a939 RL |
79 | return 0; \ |
80 | } | |
81 | # define IMPLEMENT_PEM_provided_write_body_main(type, outtype) \ | |
ece9304c RL |
82 | ret = OSSL_ENCODER_to_##outtype(ctx, out); \ |
83 | OSSL_ENCODER_CTX_free(ctx); \ | |
f864a939 RL |
84 | return ret |
85 | # define IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \ | |
86 | writename) \ | |
87 | legacy: \ | |
88 | return PEM_ASN1_##writename((i2d_of_void *)i2d_##asn1, str, out, \ | |
ece9304c | 89 | x, NULL, NULL, 0, NULL, NULL) |
f864a939 RL |
90 | # define IMPLEMENT_PEM_provided_write_body_fallback_cb(str, asn1, \ |
91 | writename) \ | |
92 | legacy: \ | |
9256e8a2 RL |
93 | return PEM_ASN1_##writename##((i2d_of_void *)i2d_##asn1, str, out, \ |
94 | x, enc, kstr, klen, cb, u) | |
f864a939 | 95 | |
fe75766c | 96 | # define IMPLEMENT_PEM_provided_write_to(name, TYPE, type, str, asn1, \ |
f864a939 | 97 | OUTTYPE, outtype, writename) \ |
fe75766c | 98 | PEM_write_fnsig(name, TYPE, OUTTYPE, writename) \ |
f864a939 | 99 | { \ |
9256e8a2 RL |
100 | IMPLEMENT_PEM_provided_write_body_vars(type, asn1, NULL); \ |
101 | IMPLEMENT_PEM_provided_write_body_main(type, outtype); \ | |
102 | IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \ | |
103 | writename); \ | |
104 | } \ | |
fe75766c | 105 | PEM_write_ex_fnsig(name, TYPE, OUTTYPE, writename) \ |
9256e8a2 RL |
106 | { \ |
107 | IMPLEMENT_PEM_provided_write_body_vars(type, asn1, propq); \ | |
f864a939 RL |
108 | IMPLEMENT_PEM_provided_write_body_main(type, outtype); \ |
109 | IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \ | |
110 | writename); \ | |
111 | } | |
112 | ||
113 | ||
fe75766c | 114 | # define IMPLEMENT_PEM_provided_write_cb_to(name, TYPE, type, str, asn1, \ |
f864a939 | 115 | OUTTYPE, outtype, writename) \ |
fe75766c | 116 | PEM_write_cb_fnsig(name, TYPE, OUTTYPE, writename) \ |
f864a939 | 117 | { \ |
9256e8a2 | 118 | IMPLEMENT_PEM_provided_write_body_vars(type, asn1, NULL); \ |
f864a939 RL |
119 | IMPLEMENT_PEM_provided_write_body_pass(); \ |
120 | IMPLEMENT_PEM_provided_write_body_main(type, outtype); \ | |
121 | IMPLEMENT_PEM_provided_write_body_fallback_cb(str, asn1, \ | |
122 | writename); \ | |
9256e8a2 | 123 | } \ |
fe75766c | 124 | PEM_write_ex_cb_fnsig(name, TYPE, OUTTYPE, writename) \ |
9256e8a2 RL |
125 | { \ |
126 | IMPLEMENT_PEM_provided_write_body_vars(type, asn1, propq); \ | |
127 | IMPLEMENT_PEM_provided_write_body_pass(); \ | |
128 | IMPLEMENT_PEM_provided_write_body_main(type, outtype); \ | |
129 | IMPLEMENT_PEM_provided_write_body_fallback(str, asn1, \ | |
130 | writename); \ | |
f864a939 RL |
131 | } |
132 | ||
133 | # ifdef OPENSSL_NO_STDIO | |
134 | ||
fe75766c TM |
135 | # define IMPLEMENT_PEM_provided_write_fp(name, TYPE, type, str, asn1) |
136 | # define IMPLEMENT_PEM_provided_write_cb_fp(name, TYPE, type, str, asn1) | |
f864a939 RL |
137 | |
138 | # else | |
139 | ||
fe75766c TM |
140 | # define IMPLEMENT_PEM_provided_write_fp(name, TYPE, type, str, asn1) \ |
141 | IMPLEMENT_PEM_provided_write_to(name, TYPE, type, str, asn1, FILE, fp, write) | |
142 | # define IMPLEMENT_PEM_provided_write_cb_fp(name, TYPE, type, str, asn1) \ | |
143 | IMPLEMENT_PEM_provided_write_cb_to(name, TYPE, type, str, asn1, FILE, fp, write) | |
f864a939 RL |
144 | |
145 | # endif | |
146 | ||
fe75766c TM |
147 | # define IMPLEMENT_PEM_provided_write_bio(name, TYPE, type, str, asn1) \ |
148 | IMPLEMENT_PEM_provided_write_to(name, TYPE, type, str, asn1, BIO, bio, write_bio) | |
149 | # define IMPLEMENT_PEM_provided_write_cb_bio(name, TYPE, type, str, asn1) \ | |
150 | IMPLEMENT_PEM_provided_write_cb_to(name, TYPE, type, str, asn1, BIO, bio, write_bio) | |
f864a939 | 151 | |
fe75766c TM |
152 | # define IMPLEMENT_PEM_provided_write(name, TYPE, type, str, asn1) \ |
153 | IMPLEMENT_PEM_provided_write_bio(name, TYPE, type, str, asn1) \ | |
154 | IMPLEMENT_PEM_provided_write_fp(name, TYPE, type, str, asn1) | |
f864a939 | 155 | |
fe75766c TM |
156 | # define IMPLEMENT_PEM_provided_write_cb(name, TYPE, type, str, asn1) \ |
157 | IMPLEMENT_PEM_provided_write_cb_bio(name, TYPE, type, str, asn1) \ | |
158 | IMPLEMENT_PEM_provided_write_cb_fp(name, TYPE, type, str, asn1) | |
f864a939 | 159 | |
fe75766c TM |
160 | # define IMPLEMENT_PEM_provided_rw(name, TYPE, type, str, asn1) \ |
161 | IMPLEMENT_PEM_read(name, TYPE, str, asn1) \ | |
162 | IMPLEMENT_PEM_provided_write(name, TYPE, type, str, asn1) | |
f864a939 | 163 | |
fe75766c TM |
164 | # define IMPLEMENT_PEM_provided_rw_cb(name, TYPE, type, str, asn1) \ |
165 | IMPLEMENT_PEM_read(name, TYPE, str, asn1) \ | |
166 | IMPLEMENT_PEM_provided_write_cb(name, TYPE, type, str, asn1) | |
f864a939 | 167 |