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