117 {
118
121 return true;
122 }
123
124 EVP_PKEY *private_key;
125
126 BIO *bio = BIO_new(BIO_s_mem());
127 if (bio == NULL) {
128 return false;
129 }
130
131 (void) BIO_write(bio,
buf,
len);
132
133 private_key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
134 BIO_free_all(bio);
135 if (private_key == NULL) {
136 return false;
137 }
138
140
141 RSA *rsa = NULL;
142
145 EC_KEY *ec_private = NULL;
146
147 switch (EVP_PKEY_base_id(private_key)) {
148 case EVP_PKEY_RSA: {
149 rsa = EVP_PKEY_get1_RSA(private_key);
150 unsigned char e[4];
151 int size = RSA_size(rsa);
152 const BIGNUM *bn_n, *bn_e, *bn_p, *bn_q;
153
156
158 !(e[0] == 0x01 && e[1] == 0x00 && e[2] == 0x01)) {
159 goto cleanup;
160 }
161
162 if (size == 256) {
164 } else if (size == 384) {
166 } else if (size == 512) {
168 } else {
169 goto cleanup;
170 }
171
173 goto cleanup;
174 }
175
176 if (
set_component(bytes + size / 2, bn_q, size / 2) ==
false) {
177 goto cleanup;
178 }
179
180 if (internal_repr == true) {
181 const BIGNUM *dmp1, *dmq1, *iqmp;
183
186 goto cleanup;
187 }
188 ptr += size / 2;
189
191 goto cleanup;
192 }
193 ptr += size / 2;
194
196 goto cleanup;
197 }
198 ptr += size / 2;
199
201 goto cleanup;
202 }
203
204 *bytes_len = (size / 2) * 7;
205 } else {
206 *bytes_len = size;
207 }
208 } break;
209
210 case EVP_PKEY_EC: {
211 ec_private = EVP_PKEY_get1_EC_KEY(private_key);
212 if (ec_private == NULL) {
213 goto cleanup;
214 }
215
216 const BIGNUM *
s = EC_KEY_get0_private_key(ec_private);
217 const EC_GROUP *group = EC_KEY_get0_group(ec_private);
218 int curve = EC_GROUP_get_curve_name(group);
219 int size = 0;
220
221 if (curve == NID_X9_62_prime256v1) {
223 size = 32;
224 } else if (curve == NID_secp384r1) {
226 size = 48;
227 } else if (curve == NID_secp521r1) {
229 size = 66;
230 } else if (curve == NID_secp224r1) {
232 size = 28;
233#ifdef NID_brainpoolP256r1
234 } else if (curve == NID_brainpoolP256r1) {
236 size = 32;
237#endif
238#ifdef NID_brainpoolP384r1
239 } else if (curve == NID_brainpoolP384r1) {
241 size = 48;
242#endif
243#ifdef NID_brainpoolP512r1
244 } else if (curve == NID_brainpoolP512r1) {
246 size = 64;
247#endif
248 } else if (curve == NID_secp256k1) {
250 size = 32;
251 } else {
252 goto cleanup;
253 }
254
256 goto cleanup;
257 }
258
259 if (internal_repr == true) {
260 const EC_POINT *ec_public = EC_KEY_get0_public_key(ec_private);
261
262 x = BN_new();
263 if (x == NULL) {
264 goto cleanup;
265 }
266
268 if (y == NULL) {
269 goto cleanup;
270 }
271
272 if (EC_POINT_get_affine_coordinates_GFp(group, ec_public, x, y, NULL) ==
273 0) {
274 goto cleanup;
275 }
276
279 goto cleanup;
280 }
281 ptr += size;
282
284 goto cleanup;
285 }
286
287 *bytes_len = size * 3;
288 } else {
289 *bytes_len = size;
290 }
291 } break;
292
293 default:
294 goto cleanup;
295 }
296
298
299cleanup:
300
301 if (rsa != NULL) {
302 RSA_free(rsa);
303 rsa = NULL;
304 }
305
306 if (x != NULL) {
307 BN_free(x);
308 x = NULL;
309 }
310
311 if (y != NULL) {
312 BN_free(y);
314 }
315
316 if (ec_private != NULL) {
317 EC_KEY_free(ec_private);
318 ec_private = NULL;
319 }
320
321 EVP_PKEY_free(private_key);
322
324}
void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp)
void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
bool read_ed25519_key(uint8_t *in, size_t in_len, uint8_t *out, size_t *out_len)
bool set_component(unsigned char *in_ptr, const BIGNUM *bn, int element_len)