summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pem
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/pem')
-rw-r--r--src/lib/libcrypto/pem/message16
-rw-r--r--src/lib/libcrypto/pem/pem.h546
-rw-r--r--src/lib/libcrypto/pem/pem_all.c704
-rw-r--r--src/lib/libcrypto/pem/pem_err.c119
-rw-r--r--src/lib/libcrypto/pem/pem_info.c387
-rw-r--r--src/lib/libcrypto/pem/pem_lib.c866
-rw-r--r--src/lib/libcrypto/pem/pem_oth.c88
-rw-r--r--src/lib/libcrypto/pem/pem_pk8.c324
-rw-r--r--src/lib/libcrypto/pem/pem_pkey.c263
-rw-r--r--src/lib/libcrypto/pem/pem_sign.c108
-rw-r--r--src/lib/libcrypto/pem/pem_x509.c98
-rw-r--r--src/lib/libcrypto/pem/pem_xaux.c98
-rw-r--r--src/lib/libcrypto/pem/pkcs7.lis22
-rw-r--r--src/lib/libcrypto/pem/pvkfmt.c944
14 files changed, 0 insertions, 4583 deletions
diff --git a/src/lib/libcrypto/pem/message b/src/lib/libcrypto/pem/message
deleted file mode 100644
index e8bf9d7592..0000000000
--- a/src/lib/libcrypto/pem/message
+++ /dev/null
@@ -1,16 +0,0 @@
1-----BEGIN PRIVACY-ENHANCED MESSAGE-----
2Proc-Type: 4,ENCRYPTED
3Proc-Type: 4,MIC-ONLY
4Proc-Type: 4,MIC-CLEAR
5Content-Domain: RFC822
6DEK-Info: DES-CBC,0123456789abcdef
7Originator-Certificate
8 xxxx
9Issuer-Certificate
10 xxxx
11MIC-Info: RSA-MD5,RSA,
12 xxxx
13
14
15-----END PRIVACY-ENHANCED MESSAGE-----
16
diff --git a/src/lib/libcrypto/pem/pem.h b/src/lib/libcrypto/pem/pem.h
deleted file mode 100644
index 4fdab48bb2..0000000000
--- a/src/lib/libcrypto/pem/pem.h
+++ /dev/null
@@ -1,546 +0,0 @@
1/* $OpenBSD: pem.h,v 1.28 2024/05/11 05:41:28 tb Exp $ */
2/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#ifndef HEADER_PEM_H
60#define HEADER_PEM_H
61
62#include <openssl/opensslconf.h>
63
64#ifndef OPENSSL_NO_BIO
65#include <openssl/bio.h>
66#endif
67#ifndef OPENSSL_NO_STACK
68#include <openssl/stack.h>
69#endif
70#include <openssl/evp.h>
71#include <openssl/x509.h>
72
73#ifdef __cplusplus
74extern "C" {
75#endif
76
77#define PEM_BUFSIZE 1024
78
79#define PEM_OBJ_UNDEF 0
80#define PEM_OBJ_X509 1
81#define PEM_OBJ_X509_REQ 2
82#define PEM_OBJ_CRL 3
83#define PEM_OBJ_SSL_SESSION 4
84#define PEM_OBJ_PRIV_KEY 10
85#define PEM_OBJ_PRIV_RSA 11
86#define PEM_OBJ_PRIV_DSA 12
87#define PEM_OBJ_PRIV_DH 13
88#define PEM_OBJ_PUB_RSA 14
89#define PEM_OBJ_PUB_DSA 15
90#define PEM_OBJ_PUB_DH 16
91#define PEM_OBJ_DHPARAMS 17
92#define PEM_OBJ_DSAPARAMS 18
93#define PEM_OBJ_PRIV_RSA_PUBLIC 19
94#define PEM_OBJ_PRIV_ECDSA 20
95#define PEM_OBJ_PUB_ECDSA 21
96#define PEM_OBJ_ECPARAMETERS 22
97
98#define PEM_ERROR 30
99#define PEM_DEK_DES_CBC 40
100#define PEM_DEK_IDEA_CBC 45
101#define PEM_DEK_DES_EDE 50
102#define PEM_DEK_DES_ECB 60
103#define PEM_DEK_RSA 70
104#define PEM_DEK_RSA_MD2 80
105#define PEM_DEK_RSA_MD5 90
106
107#define PEM_MD_MD2 NID_md2
108#define PEM_MD_MD5 NID_md5
109#define PEM_MD_SHA NID_sha
110#define PEM_MD_MD2_RSA NID_md2WithRSAEncryption
111#define PEM_MD_MD5_RSA NID_md5WithRSAEncryption
112#define PEM_MD_SHA_RSA NID_sha1WithRSAEncryption
113
114#define PEM_STRING_X509_OLD "X509 CERTIFICATE"
115#define PEM_STRING_X509 "CERTIFICATE"
116#define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE"
117#define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST"
118#define PEM_STRING_X509_REQ "CERTIFICATE REQUEST"
119#define PEM_STRING_X509_CRL "X509 CRL"
120#define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY"
121#define PEM_STRING_PUBLIC "PUBLIC KEY"
122#define PEM_STRING_RSA "RSA PRIVATE KEY"
123#define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY"
124#define PEM_STRING_DSA "DSA PRIVATE KEY"
125#define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY"
126#define PEM_STRING_PKCS7 "PKCS7"
127#define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA"
128#define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY"
129#define PEM_STRING_PKCS8INF "PRIVATE KEY"
130#define PEM_STRING_DHPARAMS "DH PARAMETERS"
131#define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS"
132#define PEM_STRING_DSAPARAMS "DSA PARAMETERS"
133#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
134#define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
135#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
136#define PEM_STRING_PARAMETERS "PARAMETERS"
137#define PEM_STRING_CMS "CMS"
138
139/* enc_type is one off */
140#define PEM_TYPE_ENCRYPTED 10
141#define PEM_TYPE_MIC_ONLY 20
142#define PEM_TYPE_MIC_CLEAR 30
143#define PEM_TYPE_CLEAR 40
144
145#ifndef LIBRESSL_INTERNAL
146/* These macros make the PEM_read/PEM_write functions easier to maintain and
147 * write. Now they are all implemented with either:
148 * IMPLEMENT_PEM_rw(...) or IMPLEMENT_PEM_rw_cb(...)
149 */
150
151#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
152type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
153{ \
154return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \
155}
156
157#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
158int PEM_write_##name(FILE *fp, type *x) \
159{ \
160return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \
161}
162
163#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
164int PEM_write_##name(FILE *fp, const type *x) \
165{ \
166return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \
167}
168
169#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
170int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
171 unsigned char *kstr, int klen, pem_password_cb *cb, \
172 void *u) \
173 { \
174 return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
175 }
176
177#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
178int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
179 unsigned char *kstr, int klen, pem_password_cb *cb, \
180 void *u) \
181 { \
182 return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
183 }
184
185
186#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
187type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
188{ \
189return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \
190}
191
192#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
193int PEM_write_bio_##name(BIO *bp, type *x) \
194{ \
195return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \
196}
197
198#define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
199int PEM_write_bio_##name(BIO *bp, const type *x) \
200{ \
201return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \
202}
203
204#define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
205int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
206 unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
207 { \
208 return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \
209 }
210
211#define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
212int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
213 unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
214 { \
215 return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \
216 }
217
218#define IMPLEMENT_PEM_write(name, type, str, asn1) \
219 IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
220 IMPLEMENT_PEM_write_fp(name, type, str, asn1)
221
222#define IMPLEMENT_PEM_write_const(name, type, str, asn1) \
223 IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
224 IMPLEMENT_PEM_write_fp_const(name, type, str, asn1)
225
226#define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \
227 IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
228 IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1)
229
230#define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \
231 IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
232 IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1)
233
234#define IMPLEMENT_PEM_read(name, type, str, asn1) \
235 IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
236 IMPLEMENT_PEM_read_fp(name, type, str, asn1)
237
238#define IMPLEMENT_PEM_rw(name, type, str, asn1) \
239 IMPLEMENT_PEM_read(name, type, str, asn1) \
240 IMPLEMENT_PEM_write(name, type, str, asn1)
241
242#define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \
243 IMPLEMENT_PEM_read(name, type, str, asn1) \
244 IMPLEMENT_PEM_write_const(name, type, str, asn1)
245
246#define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \
247 IMPLEMENT_PEM_read(name, type, str, asn1) \
248 IMPLEMENT_PEM_write_cb(name, type, str, asn1)
249
250#endif
251
252/* These are the same except they are for the declarations */
253
254
255#define DECLARE_PEM_read_fp(name, type) \
256 type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u);
257
258#define DECLARE_PEM_write_fp(name, type) \
259 int PEM_write_##name(FILE *fp, type *x);
260
261#define DECLARE_PEM_write_fp_const(name, type) \
262 int PEM_write_##name(FILE *fp, const type *x);
263
264#define DECLARE_PEM_write_cb_fp(name, type) \
265 int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
266 unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
267
268
269#ifndef OPENSSL_NO_BIO
270#define DECLARE_PEM_read_bio(name, type) \
271 type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u);
272
273#define DECLARE_PEM_write_bio(name, type) \
274 int PEM_write_bio_##name(BIO *bp, type *x);
275
276#define DECLARE_PEM_write_bio_const(name, type) \
277 int PEM_write_bio_##name(BIO *bp, const type *x);
278
279#define DECLARE_PEM_write_cb_bio(name, type) \
280 int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
281 unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
282
283#else
284
285#define DECLARE_PEM_read_bio(name, type) /**/
286#define DECLARE_PEM_write_bio(name, type) /**/
287#define DECLARE_PEM_write_bio_const(name, type) /**/
288#define DECLARE_PEM_write_cb_bio(name, type) /**/
289
290#endif
291
292#define DECLARE_PEM_write(name, type) \
293 DECLARE_PEM_write_bio(name, type) \
294 DECLARE_PEM_write_fp(name, type)
295
296#define DECLARE_PEM_write_const(name, type) \
297 DECLARE_PEM_write_bio_const(name, type) \
298 DECLARE_PEM_write_fp_const(name, type)
299
300#define DECLARE_PEM_write_cb(name, type) \
301 DECLARE_PEM_write_cb_bio(name, type) \
302 DECLARE_PEM_write_cb_fp(name, type)
303
304#define DECLARE_PEM_read(name, type) \
305 DECLARE_PEM_read_bio(name, type) \
306 DECLARE_PEM_read_fp(name, type)
307
308#define DECLARE_PEM_rw(name, type) \
309 DECLARE_PEM_read(name, type) \
310 DECLARE_PEM_write(name, type)
311
312#define DECLARE_PEM_rw_const(name, type) \
313 DECLARE_PEM_read(name, type) \
314 DECLARE_PEM_write_const(name, type)
315
316#define DECLARE_PEM_rw_cb(name, type) \
317 DECLARE_PEM_read(name, type) \
318 DECLARE_PEM_write_cb(name, type)
319
320typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata);
321
322int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher);
323int PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data, long *len,
324 pem_password_cb *callback, void *u);
325
326#ifndef OPENSSL_NO_BIO
327int PEM_read_bio(BIO *bp, char **name, char **header,
328 unsigned char **data, long *len);
329int PEM_write_bio(BIO *bp, const char *name, const char *hdr,
330 const unsigned char *data, long len);
331int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
332 const char *name, BIO *bp, pem_password_cb *cb, void *u);
333void * PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp,
334 void **x, pem_password_cb *cb, void *u);
335int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x,
336 const EVP_CIPHER *enc, unsigned char *kstr, int klen,
337 pem_password_cb *cb, void *u);
338
339STACK_OF(X509_INFO) * PEM_X509_INFO_read_bio(BIO *bp,
340 STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u);
341int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
342 unsigned char *kstr, int klen, pem_password_cb *cd, void *u);
343#endif
344
345int PEM_read(FILE *fp, char **name, char **header,
346 unsigned char **data, long *len);
347int PEM_write(FILE *fp, const char *name, const char *hdr,
348 const unsigned char *data, long len);
349void * PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
350 pem_password_cb *cb, void *u);
351int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
352 void *x, const EVP_CIPHER *enc, unsigned char *kstr,
353 int klen, pem_password_cb *callback, void *u);
354STACK_OF(X509_INFO) * PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
355 pem_password_cb *cb, void *u);
356
357int PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
358int PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt);
359int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
360 unsigned int *siglen, EVP_PKEY *pkey);
361
362int PEM_def_callback(char *buf, int num, int w, void *key);
363void PEM_proc_type(char *buf, int type);
364void PEM_dek_info(char *buf, const char *type, int len, char *str);
365
366
367DECLARE_PEM_rw(X509, X509)
368
369DECLARE_PEM_rw(X509_AUX, X509)
370
371DECLARE_PEM_rw(X509_REQ, X509_REQ)
372DECLARE_PEM_write(X509_REQ_NEW, X509_REQ)
373
374DECLARE_PEM_rw(X509_CRL, X509_CRL)
375
376DECLARE_PEM_rw(PKCS7, PKCS7)
377
378DECLARE_PEM_rw(PKCS8, X509_SIG)
379
380DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
381
382#ifndef OPENSSL_NO_RSA
383
384DECLARE_PEM_rw_cb(RSAPrivateKey, RSA)
385
386DECLARE_PEM_rw_const(RSAPublicKey, RSA)
387DECLARE_PEM_rw(RSA_PUBKEY, RSA)
388
389#endif
390
391#ifndef OPENSSL_NO_DSA
392
393DECLARE_PEM_rw_cb(DSAPrivateKey, DSA)
394
395DECLARE_PEM_rw(DSA_PUBKEY, DSA)
396
397DECLARE_PEM_rw_const(DSAparams, DSA)
398
399#endif
400
401#ifndef OPENSSL_NO_EC
402DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP)
403DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY)
404DECLARE_PEM_rw(EC_PUBKEY, EC_KEY)
405#endif
406
407#ifndef OPENSSL_NO_DH
408
409DECLARE_PEM_rw_const(DHparams, DH)
410
411#endif
412
413DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY)
414
415DECLARE_PEM_rw(PUBKEY, EVP_PKEY)
416
417int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x,
418 const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb,
419 void *u);
420int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
421 char *kstr, int klen,
422 pem_password_cb *cb, void *u);
423int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
424 char *, int, pem_password_cb *, void *);
425int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
426 char *kstr, int klen,
427 pem_password_cb *cb, void *u);
428int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
429 char *kstr, int klen,
430 pem_password_cb *cb, void *u);
431EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
432 void *u);
433
434int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
435 char *kstr, int klen,
436 pem_password_cb *cb, void *u);
437int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
438 char *kstr, int klen,
439 pem_password_cb *cb, void *u);
440int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
441 char *kstr, int klen,
442 pem_password_cb *cb, void *u);
443
444EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
445 void *u);
446
447int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
448 char *kstr, int klen, pem_password_cb *cd, void *u);
449
450EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
451int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
452
453
454EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
455EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
456EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
457EVP_PKEY *b2i_PublicKey_bio(BIO *in);
458int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk);
459int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk);
460#ifndef OPENSSL_NO_RC4
461EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u);
462int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, pem_password_cb *cb,
463 void *u);
464#endif
465
466
467void ERR_load_PEM_strings(void);
468
469/* Error codes for the PEM functions. */
470
471/* Function codes. */
472#define PEM_F_B2I_DSS 127
473#define PEM_F_B2I_PVK_BIO 128
474#define PEM_F_B2I_RSA 129
475#define PEM_F_CHECK_BITLEN_DSA 130
476#define PEM_F_CHECK_BITLEN_RSA 131
477#define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120
478#define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121
479#define PEM_F_DO_B2I 132
480#define PEM_F_DO_B2I_BIO 133
481#define PEM_F_DO_BLOB_HEADER 134
482#define PEM_F_DO_PK8PKEY 126
483#define PEM_F_DO_PK8PKEY_FP 125
484#define PEM_F_DO_PVK_BODY 135
485#define PEM_F_DO_PVK_HEADER 136
486#define PEM_F_I2B_PVK 137
487#define PEM_F_I2B_PVK_BIO 138
488#define PEM_F_LOAD_IV 101
489#define PEM_F_PEM_ASN1_READ 102
490#define PEM_F_PEM_ASN1_READ_BIO 103
491#define PEM_F_PEM_ASN1_WRITE 104
492#define PEM_F_PEM_ASN1_WRITE_BIO 105
493#define PEM_F_PEM_DEF_CALLBACK 100
494#define PEM_F_PEM_DO_HEADER 106
495#define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY 118
496#define PEM_F_PEM_GET_EVP_CIPHER_INFO 107
497#define PEM_F_PEM_PK8PKEY 119
498#define PEM_F_PEM_READ 108
499#define PEM_F_PEM_READ_BIO 109
500#define PEM_F_PEM_READ_BIO_PARAMETERS 140
501#define PEM_F_PEM_READ_BIO_PRIVATEKEY 123
502#define PEM_F_PEM_READ_PRIVATEKEY 124
503#define PEM_F_PEM_SEALFINAL 110
504#define PEM_F_PEM_SEALINIT 111
505#define PEM_F_PEM_SIGNFINAL 112
506#define PEM_F_PEM_WRITE 113
507#define PEM_F_PEM_WRITE_BIO 114
508#define PEM_F_PEM_WRITE_PRIVATEKEY 139
509#define PEM_F_PEM_X509_INFO_READ 115
510#define PEM_F_PEM_X509_INFO_READ_BIO 116
511#define PEM_F_PEM_X509_INFO_WRITE_BIO 117
512
513/* Reason codes. */
514#define PEM_R_BAD_BASE64_DECODE 100
515#define PEM_R_BAD_DECRYPT 101
516#define PEM_R_BAD_END_LINE 102
517#define PEM_R_BAD_IV_CHARS 103
518#define PEM_R_BAD_MAGIC_NUMBER 116
519#define PEM_R_BAD_PASSWORD_READ 104
520#define PEM_R_BAD_VERSION_NUMBER 117
521#define PEM_R_BIO_WRITE_FAILURE 118
522#define PEM_R_CIPHER_IS_NULL 127
523#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115
524#define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119
525#define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120
526#define PEM_R_INCONSISTENT_HEADER 121
527#define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122
528#define PEM_R_KEYBLOB_TOO_SHORT 123
529#define PEM_R_NOT_DEK_INFO 105
530#define PEM_R_NOT_ENCRYPTED 106
531#define PEM_R_NOT_PROC_TYPE 107
532#define PEM_R_NO_START_LINE 108
533#define PEM_R_PROBLEMS_GETTING_PASSWORD 109
534#define PEM_R_PUBLIC_KEY_NO_RSA 110
535#define PEM_R_PVK_DATA_TOO_SHORT 124
536#define PEM_R_PVK_TOO_SHORT 125
537#define PEM_R_READ_KEY 111
538#define PEM_R_SHORT_HEADER 112
539#define PEM_R_UNSUPPORTED_CIPHER 113
540#define PEM_R_UNSUPPORTED_ENCRYPTION 114
541#define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126
542
543#ifdef __cplusplus
544}
545#endif
546#endif
diff --git a/src/lib/libcrypto/pem/pem_all.c b/src/lib/libcrypto/pem/pem_all.c
deleted file mode 100644
index 21e325b9f1..0000000000
--- a/src/lib/libcrypto/pem/pem_all.c
+++ /dev/null
@@ -1,704 +0,0 @@
1/* $OpenBSD: pem_all.c,v 1.21 2023/07/07 13:40:44 beck Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58/* ====================================================================
59 * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
111
112#include <stdio.h>
113
114#include <openssl/opensslconf.h>
115
116#include <openssl/bio.h>
117#include <openssl/evp.h>
118#include <openssl/pem.h>
119#include <openssl/pkcs7.h>
120#include <openssl/x509.h>
121
122#ifndef OPENSSL_NO_DH
123#include <openssl/dh.h>
124#endif
125#ifndef OPENSSL_NO_DSA
126#include <openssl/dsa.h>
127#endif
128#ifndef OPENSSL_NO_RSA
129#include <openssl/rsa.h>
130#endif
131
132#ifndef OPENSSL_NO_RSA
133static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa);
134#endif
135#ifndef OPENSSL_NO_DSA
136static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa);
137#endif
138
139#ifndef OPENSSL_NO_EC
140static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey);
141#endif
142
143
144X509_REQ *
145PEM_read_X509_REQ(FILE *fp, X509_REQ **x, pem_password_cb *cb, void *u)
146{
147 return PEM_ASN1_read((d2i_of_void *)d2i_X509_REQ, PEM_STRING_X509_REQ, fp,
148 (void **)x, cb, u);
149}
150LCRYPTO_ALIAS(PEM_read_X509_REQ);
151
152int
153PEM_write_X509_REQ(FILE *fp, X509_REQ *x)
154{
155 return PEM_ASN1_write((i2d_of_void *)i2d_X509_REQ, PEM_STRING_X509_REQ, fp,
156 x, NULL, NULL, 0, NULL, NULL);
157}
158LCRYPTO_ALIAS(PEM_write_X509_REQ);
159
160X509_REQ *
161PEM_read_bio_X509_REQ(BIO *bp, X509_REQ **x, pem_password_cb *cb, void *u)
162{
163 return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509_REQ, PEM_STRING_X509_REQ, bp,
164 (void **)x, cb, u);
165}
166LCRYPTO_ALIAS(PEM_read_bio_X509_REQ);
167
168int
169PEM_write_bio_X509_REQ(BIO *bp, X509_REQ *x)
170{
171 return PEM_ASN1_write_bio((i2d_of_void *)i2d_X509_REQ, PEM_STRING_X509_REQ, bp,
172 x, NULL, NULL, 0, NULL, NULL);
173}
174LCRYPTO_ALIAS(PEM_write_bio_X509_REQ);
175
176int
177PEM_write_X509_REQ_NEW(FILE *fp, X509_REQ *x)
178{
179 return PEM_ASN1_write((i2d_of_void *)i2d_X509_REQ, PEM_STRING_X509_REQ_OLD, fp,
180 x, NULL, NULL, 0, NULL, NULL);
181}
182LCRYPTO_ALIAS(PEM_write_X509_REQ_NEW);
183
184int
185PEM_write_bio_X509_REQ_NEW(BIO *bp, X509_REQ *x)
186{
187 return PEM_ASN1_write_bio((i2d_of_void *)i2d_X509_REQ, PEM_STRING_X509_REQ_OLD, bp,
188 x, NULL, NULL, 0, NULL, NULL);
189}
190LCRYPTO_ALIAS(PEM_write_bio_X509_REQ_NEW);
191
192X509_CRL *
193PEM_read_X509_CRL(FILE *fp, X509_CRL **x, pem_password_cb *cb, void *u)
194{
195 return PEM_ASN1_read((d2i_of_void *)d2i_X509_CRL, PEM_STRING_X509_CRL, fp,
196 (void **)x, cb, u);
197}
198LCRYPTO_ALIAS(PEM_read_X509_CRL);
199
200int
201PEM_write_X509_CRL(FILE *fp, X509_CRL *x)
202{
203 return PEM_ASN1_write((i2d_of_void *)i2d_X509_CRL, PEM_STRING_X509_CRL, fp,
204 x, NULL, NULL, 0, NULL, NULL);
205}
206LCRYPTO_ALIAS(PEM_write_X509_CRL);
207
208X509_CRL *
209PEM_read_bio_X509_CRL(BIO *bp, X509_CRL **x, pem_password_cb *cb, void *u)
210{
211 return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509_CRL, PEM_STRING_X509_CRL, bp,
212 (void **)x, cb, u);
213}
214LCRYPTO_ALIAS(PEM_read_bio_X509_CRL);
215
216int
217PEM_write_bio_X509_CRL(BIO *bp, X509_CRL *x)
218{
219 return PEM_ASN1_write_bio((i2d_of_void *)i2d_X509_CRL, PEM_STRING_X509_CRL, bp,
220 x, NULL, NULL, 0, NULL, NULL);
221}
222LCRYPTO_ALIAS(PEM_write_bio_X509_CRL);
223
224PKCS7 *
225PEM_read_PKCS7(FILE *fp, PKCS7 **x, pem_password_cb *cb, void *u)
226{
227 return PEM_ASN1_read((d2i_of_void *)d2i_PKCS7, PEM_STRING_PKCS7, fp,
228 (void **)x, cb, u);
229}
230LCRYPTO_ALIAS(PEM_read_PKCS7);
231
232int
233PEM_write_PKCS7(FILE *fp, PKCS7 *x)
234{
235 return PEM_ASN1_write((i2d_of_void *)i2d_PKCS7, PEM_STRING_PKCS7, fp,
236 x, NULL, NULL, 0, NULL, NULL);
237}
238LCRYPTO_ALIAS(PEM_write_PKCS7);
239
240PKCS7 *
241PEM_read_bio_PKCS7(BIO *bp, PKCS7 **x, pem_password_cb *cb, void *u)
242{
243 return PEM_ASN1_read_bio((d2i_of_void *)d2i_PKCS7, PEM_STRING_PKCS7, bp,
244 (void **)x, cb, u);
245}
246LCRYPTO_ALIAS(PEM_read_bio_PKCS7);
247
248int
249PEM_write_bio_PKCS7(BIO *bp, PKCS7 *x)
250{
251 return PEM_ASN1_write_bio((i2d_of_void *)i2d_PKCS7, PEM_STRING_PKCS7, bp,
252 x, NULL, NULL, 0, NULL, NULL);
253}
254LCRYPTO_ALIAS(PEM_write_bio_PKCS7);
255
256#ifndef OPENSSL_NO_RSA
257
258/* We treat RSA or DSA private keys as a special case.
259 *
260 * For private keys we read in an EVP_PKEY structure with
261 * PEM_read_bio_PrivateKey() and extract the relevant private
262 * key: this means can handle "traditional" and PKCS#8 formats
263 * transparently.
264 */
265
266static RSA *
267pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
268{
269 RSA *rtmp;
270
271 if (!key)
272 return NULL;
273 rtmp = EVP_PKEY_get1_RSA(key);
274 EVP_PKEY_free(key);
275 if (!rtmp)
276 return NULL;
277 if (rsa) {
278 RSA_free(*rsa);
279 *rsa = rtmp;
280 }
281 return rtmp;
282}
283
284RSA *
285PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u)
286{
287 EVP_PKEY *pktmp;
288
289 pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
290 return pkey_get_rsa(pktmp, rsa);
291}
292LCRYPTO_ALIAS(PEM_read_RSAPrivateKey);
293
294int
295PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
296 unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
297{
298 return PEM_ASN1_write((i2d_of_void *)i2d_RSAPrivateKey, PEM_STRING_RSA, fp,
299 x, enc, kstr, klen, cb, u);
300}
301LCRYPTO_ALIAS(PEM_write_RSAPrivateKey);
302
303RSA *
304PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb, void *u)
305{
306 EVP_PKEY *pktmp;
307
308 pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
309 return pkey_get_rsa(pktmp, rsa);
310}
311LCRYPTO_ALIAS(PEM_read_bio_RSAPrivateKey);
312
313int
314PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x,
315 const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb,
316 void *u)
317{
318 return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPrivateKey, PEM_STRING_RSA, bp,
319 x, enc, kstr, klen, cb, u);
320}
321LCRYPTO_ALIAS(PEM_write_bio_RSAPrivateKey);
322
323RSA *
324PEM_read_RSAPublicKey(FILE *fp, RSA **x, pem_password_cb *cb, void *u)
325{
326 return PEM_ASN1_read((d2i_of_void *)d2i_RSAPublicKey, PEM_STRING_RSA_PUBLIC, fp,
327 (void **)x, cb, u);
328}
329LCRYPTO_ALIAS(PEM_read_RSAPublicKey);
330
331int
332PEM_write_RSAPublicKey(FILE *fp, const RSA *x)
333{
334 return PEM_ASN1_write((i2d_of_void *)i2d_RSAPublicKey, PEM_STRING_RSA_PUBLIC, fp,
335 (void *)x, NULL, NULL, 0, NULL, NULL);
336}
337LCRYPTO_ALIAS(PEM_write_RSAPublicKey);
338
339RSA *
340PEM_read_bio_RSAPublicKey(BIO *bp, RSA **x, pem_password_cb *cb, void *u)
341{
342 return PEM_ASN1_read_bio((d2i_of_void *)d2i_RSAPublicKey, PEM_STRING_RSA_PUBLIC, bp,
343 (void **)x, cb, u);
344}
345LCRYPTO_ALIAS(PEM_read_bio_RSAPublicKey);
346
347int
348PEM_write_bio_RSAPublicKey(BIO *bp, const RSA *x)
349{
350 return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPublicKey, PEM_STRING_RSA_PUBLIC, bp,
351 (void *)x, NULL, NULL, 0, NULL, NULL);
352}
353LCRYPTO_ALIAS(PEM_write_bio_RSAPublicKey);
354
355RSA *
356PEM_read_RSA_PUBKEY(FILE *fp, RSA **x, pem_password_cb *cb, void *u)
357{
358 return PEM_ASN1_read((d2i_of_void *)d2i_RSA_PUBKEY, PEM_STRING_PUBLIC, fp,
359 (void **)x, cb, u);
360}
361LCRYPTO_ALIAS(PEM_read_RSA_PUBKEY);
362
363int
364PEM_write_RSA_PUBKEY(FILE *fp, RSA *x)
365{
366 return PEM_ASN1_write((i2d_of_void *)i2d_RSA_PUBKEY, PEM_STRING_PUBLIC, fp,
367 x, NULL, NULL, 0, NULL, NULL);
368}
369LCRYPTO_ALIAS(PEM_write_RSA_PUBKEY);
370
371RSA *
372PEM_read_bio_RSA_PUBKEY(BIO *bp, RSA **x, pem_password_cb *cb, void *u)
373{
374 return PEM_ASN1_read_bio((d2i_of_void *)d2i_RSA_PUBKEY, PEM_STRING_PUBLIC, bp,
375 (void **)x, cb, u);
376}
377LCRYPTO_ALIAS(PEM_read_bio_RSA_PUBKEY);
378
379int
380PEM_write_bio_RSA_PUBKEY(BIO *bp, RSA *x)
381{
382 return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSA_PUBKEY, PEM_STRING_PUBLIC, bp,
383 x, NULL, NULL, 0, NULL, NULL);
384}
385LCRYPTO_ALIAS(PEM_write_bio_RSA_PUBKEY);
386
387#endif
388
389#ifndef OPENSSL_NO_DSA
390
391static DSA *
392pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
393{
394 DSA *dtmp;
395
396 if (!key)
397 return NULL;
398 dtmp = EVP_PKEY_get1_DSA(key);
399 EVP_PKEY_free(key);
400 if (!dtmp)
401 return NULL;
402 if (dsa) {
403 DSA_free(*dsa);
404 *dsa = dtmp;
405 }
406 return dtmp;
407}
408
409DSA *
410PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u)
411{
412 EVP_PKEY *pktmp;
413
414 pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
415 return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
416}
417LCRYPTO_ALIAS(PEM_read_DSAPrivateKey);
418
419int
420PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
421 unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
422{
423 return PEM_ASN1_write((i2d_of_void *)i2d_DSAPrivateKey, PEM_STRING_DSA, fp,
424 x, enc, kstr, klen, cb, u);
425}
426LCRYPTO_ALIAS(PEM_write_DSAPrivateKey);
427
428DSA *
429PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, void *u)
430{
431 EVP_PKEY *pktmp;
432
433 pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
434 return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
435}
436LCRYPTO_ALIAS(PEM_read_bio_DSAPrivateKey);
437
438int
439PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x,
440 const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb,
441 void *u)
442{
443 return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPrivateKey, PEM_STRING_DSA, bp,
444 x, enc, kstr, klen, cb, u);
445}
446LCRYPTO_ALIAS(PEM_write_bio_DSAPrivateKey);
447
448DSA *
449PEM_read_DSA_PUBKEY(FILE *fp, DSA **x, pem_password_cb *cb, void *u)
450{
451 return PEM_ASN1_read((d2i_of_void *)d2i_DSA_PUBKEY, PEM_STRING_PUBLIC, fp,
452 (void **)x, cb, u);
453}
454LCRYPTO_ALIAS(PEM_read_DSA_PUBKEY);
455
456int
457PEM_write_DSA_PUBKEY(FILE *fp, DSA *x)
458{
459 return PEM_ASN1_write((i2d_of_void *)i2d_DSA_PUBKEY, PEM_STRING_PUBLIC, fp,
460 x, NULL, NULL, 0, NULL, NULL);
461}
462LCRYPTO_ALIAS(PEM_write_DSA_PUBKEY);
463
464int
465PEM_write_bio_DSA_PUBKEY(BIO *bp, DSA *x)
466{
467 return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSA_PUBKEY, PEM_STRING_PUBLIC, bp,
468 x, NULL, NULL, 0, NULL, NULL);
469}
470LCRYPTO_ALIAS(PEM_write_bio_DSA_PUBKEY);
471
472DSA *
473PEM_read_bio_DSA_PUBKEY(BIO *bp, DSA **x, pem_password_cb *cb, void *u)
474{
475 return PEM_ASN1_read_bio((d2i_of_void *)d2i_DSA_PUBKEY, PEM_STRING_PUBLIC, bp,
476 (void **)x, cb, u);
477}
478LCRYPTO_ALIAS(PEM_read_bio_DSA_PUBKEY);
479
480DSA *
481PEM_read_DSAparams(FILE *fp, DSA **x, pem_password_cb *cb, void *u)
482{
483 return PEM_ASN1_read((d2i_of_void *)d2i_DSAparams, PEM_STRING_DSAPARAMS, fp,
484 (void **)x, cb, u);
485}
486LCRYPTO_ALIAS(PEM_read_DSAparams);
487
488int
489PEM_write_DSAparams(FILE *fp, const DSA *x)
490{
491 return PEM_ASN1_write((i2d_of_void *)i2d_DSAparams, PEM_STRING_DSAPARAMS, fp,
492 (void *)x, NULL, NULL, 0, NULL, NULL);
493}
494LCRYPTO_ALIAS(PEM_write_DSAparams);
495
496DSA *
497PEM_read_bio_DSAparams(BIO *bp, DSA **x, pem_password_cb *cb, void *u)
498{
499 return PEM_ASN1_read_bio((d2i_of_void *)d2i_DSAparams, PEM_STRING_DSAPARAMS, bp,
500 (void **)x, cb, u);
501}
502LCRYPTO_ALIAS(PEM_read_bio_DSAparams);
503
504int
505PEM_write_bio_DSAparams(BIO *bp, const DSA *x)
506{
507 return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAparams, PEM_STRING_DSAPARAMS, bp,
508 (void *)x, NULL, NULL, 0, NULL, NULL);
509}
510LCRYPTO_ALIAS(PEM_write_bio_DSAparams);
511
512#endif
513
514
515#ifndef OPENSSL_NO_EC
516static EC_KEY *
517pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
518{
519 EC_KEY *dtmp;
520
521 if (!key)
522 return NULL;
523 dtmp = EVP_PKEY_get1_EC_KEY(key);
524 EVP_PKEY_free(key);
525 if (!dtmp)
526 return NULL;
527 if (eckey) {
528 EC_KEY_free(*eckey);
529 *eckey = dtmp;
530 }
531 return dtmp;
532}
533
534EC_GROUP *
535PEM_read_ECPKParameters(FILE *fp, EC_GROUP **x, pem_password_cb *cb, void *u)
536{
537 return PEM_ASN1_read((d2i_of_void *)d2i_ECPKParameters, PEM_STRING_ECPARAMETERS, fp,
538 (void **)x, cb, u);
539}
540LCRYPTO_ALIAS(PEM_read_ECPKParameters);
541
542int
543PEM_write_ECPKParameters(FILE *fp, const EC_GROUP *x)
544{
545 return PEM_ASN1_write((i2d_of_void *)i2d_ECPKParameters, PEM_STRING_ECPARAMETERS, fp,
546 (void *)x, NULL, NULL, 0, NULL, NULL);
547}
548LCRYPTO_ALIAS(PEM_write_ECPKParameters);
549
550EC_GROUP *
551PEM_read_bio_ECPKParameters(BIO *bp, EC_GROUP **x, pem_password_cb *cb, void *u)
552{
553 return PEM_ASN1_read_bio((d2i_of_void *)d2i_ECPKParameters, PEM_STRING_ECPARAMETERS, bp,
554 (void **)x, cb, u);
555}
556LCRYPTO_ALIAS(PEM_read_bio_ECPKParameters);
557
558int
559PEM_write_bio_ECPKParameters(BIO *bp, const EC_GROUP *x)
560{
561 return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPKParameters, PEM_STRING_ECPARAMETERS, bp,
562 (void *)x, NULL, NULL, 0, NULL, NULL);
563}
564LCRYPTO_ALIAS(PEM_write_bio_ECPKParameters);
565
566EC_KEY *
567PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, void *u)
568{
569 EVP_PKEY *pktmp;
570
571 pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
572 return pkey_get_eckey(pktmp, eckey); /* will free pktmp */
573}
574LCRYPTO_ALIAS(PEM_read_ECPrivateKey);
575
576int
577PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc,
578 unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
579{
580 return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey, PEM_STRING_ECPRIVATEKEY, fp,
581 x, enc, kstr, klen, cb, u);
582}
583LCRYPTO_ALIAS(PEM_write_ECPrivateKey);
584
585EC_KEY *
586PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, void *u)
587{
588 EVP_PKEY *pktmp;
589 pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
590 return pkey_get_eckey(pktmp, key); /* will free pktmp */
591}
592LCRYPTO_ALIAS(PEM_read_bio_ECPrivateKey);
593
594int
595PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x,
596 const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb,
597 void *u)
598{
599 return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey, PEM_STRING_ECPRIVATEKEY, bp,
600 x, enc, kstr, klen, cb, u);
601}
602LCRYPTO_ALIAS(PEM_write_bio_ECPrivateKey);
603
604EC_KEY *
605PEM_read_EC_PUBKEY(FILE *fp, EC_KEY **x, pem_password_cb *cb, void *u)
606{
607 return PEM_ASN1_read((d2i_of_void *)d2i_EC_PUBKEY, PEM_STRING_PUBLIC, fp,
608 (void **)x, cb, u);
609}
610LCRYPTO_ALIAS(PEM_read_EC_PUBKEY);
611
612int
613PEM_write_EC_PUBKEY(FILE *fp, EC_KEY *x)
614{
615 return PEM_ASN1_write((i2d_of_void *)i2d_EC_PUBKEY, PEM_STRING_PUBLIC, fp,
616 x, NULL, NULL, 0, NULL, NULL);
617}
618LCRYPTO_ALIAS(PEM_write_EC_PUBKEY);
619
620EC_KEY *
621PEM_read_bio_EC_PUBKEY(BIO *bp, EC_KEY **x, pem_password_cb *cb, void *u)
622{
623 return PEM_ASN1_read_bio((d2i_of_void *)d2i_EC_PUBKEY, PEM_STRING_PUBLIC, bp,
624 (void **)x, cb, u);
625}
626LCRYPTO_ALIAS(PEM_read_bio_EC_PUBKEY);
627
628int
629PEM_write_bio_EC_PUBKEY(BIO *bp, EC_KEY *x)
630{
631 return PEM_ASN1_write_bio((i2d_of_void *)i2d_EC_PUBKEY, PEM_STRING_PUBLIC, bp,
632 x, NULL, NULL, 0, NULL, NULL);
633}
634LCRYPTO_ALIAS(PEM_write_bio_EC_PUBKEY);
635
636#endif
637
638#ifndef OPENSSL_NO_DH
639
640DH *
641PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u)
642{
643 return PEM_ASN1_read((d2i_of_void *)d2i_DHparams, PEM_STRING_DHPARAMS, fp,
644 (void **)x, cb, u);
645}
646LCRYPTO_ALIAS(PEM_read_DHparams);
647
648int
649PEM_write_DHparams(FILE *fp, const DH *x)
650{
651 return PEM_ASN1_write((i2d_of_void *)i2d_DHparams, PEM_STRING_DHPARAMS, fp,
652 (void *)x, NULL, NULL, 0, NULL, NULL);
653}
654LCRYPTO_ALIAS(PEM_write_DHparams);
655
656DH *
657PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u)
658{
659 return PEM_ASN1_read_bio((d2i_of_void *)d2i_DHparams, PEM_STRING_DHPARAMS, bp,
660 (void **)x, cb, u);
661}
662LCRYPTO_ALIAS(PEM_read_bio_DHparams);
663
664int
665PEM_write_bio_DHparams(BIO *bp, const DH *x)
666{
667 return PEM_ASN1_write_bio((i2d_of_void *)i2d_DHparams, PEM_STRING_DHPARAMS, bp,
668 (void *)x, NULL, NULL, 0, NULL, NULL);
669}
670LCRYPTO_ALIAS(PEM_write_bio_DHparams);
671
672#endif
673
674EVP_PKEY *
675PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
676{
677 return PEM_ASN1_read((d2i_of_void *)d2i_PUBKEY, PEM_STRING_PUBLIC, fp,
678 (void **)x, cb, u);
679}
680LCRYPTO_ALIAS(PEM_read_PUBKEY);
681
682int
683PEM_write_PUBKEY(FILE *fp, EVP_PKEY *x)
684{
685 return PEM_ASN1_write((i2d_of_void *)i2d_PUBKEY, PEM_STRING_PUBLIC, fp,
686 x, NULL, NULL, 0, NULL, NULL);
687}
688LCRYPTO_ALIAS(PEM_write_PUBKEY);
689
690EVP_PKEY *
691PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
692{
693 return PEM_ASN1_read_bio((d2i_of_void *)d2i_PUBKEY, PEM_STRING_PUBLIC, bp,
694 (void **)x, cb, u);
695}
696LCRYPTO_ALIAS(PEM_read_bio_PUBKEY);
697
698int
699PEM_write_bio_PUBKEY(BIO *bp, EVP_PKEY *x)
700{
701 return PEM_ASN1_write_bio((i2d_of_void *)i2d_PUBKEY, PEM_STRING_PUBLIC, bp,
702 x, NULL, NULL, 0, NULL, NULL);
703}
704LCRYPTO_ALIAS(PEM_write_bio_PUBKEY);
diff --git a/src/lib/libcrypto/pem/pem_err.c b/src/lib/libcrypto/pem/pem_err.c
deleted file mode 100644
index 05025c8ee0..0000000000
--- a/src/lib/libcrypto/pem/pem_err.c
+++ /dev/null
@@ -1,119 +0,0 @@
1/* $OpenBSD: pem_err.c,v 1.15 2024/06/24 06:43:22 tb Exp $ */
2/* ====================================================================
3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <stdio.h>
57
58#include <openssl/opensslconf.h>
59
60#include <openssl/err.h>
61#include <openssl/pem.h>
62
63#include "err_local.h"
64
65#ifndef OPENSSL_NO_ERR
66
67#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PEM,func,0)
68#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PEM,0,reason)
69
70static const ERR_STRING_DATA PEM_str_functs[] = {
71 {ERR_FUNC(0xfff), "CRYPTO_internal"},
72 {0, NULL}
73};
74
75static const ERR_STRING_DATA PEM_str_reasons[] = {
76 {ERR_REASON(PEM_R_BAD_BASE64_DECODE) , "bad base64 decode"},
77 {ERR_REASON(PEM_R_BAD_DECRYPT) , "bad decrypt"},
78 {ERR_REASON(PEM_R_BAD_END_LINE) , "bad end line"},
79 {ERR_REASON(PEM_R_BAD_IV_CHARS) , "bad iv chars"},
80 {ERR_REASON(PEM_R_BAD_MAGIC_NUMBER) , "bad magic number"},
81 {ERR_REASON(PEM_R_BAD_PASSWORD_READ) , "bad password read"},
82 {ERR_REASON(PEM_R_BAD_VERSION_NUMBER) , "bad version number"},
83 {ERR_REASON(PEM_R_BIO_WRITE_FAILURE) , "bio write failure"},
84 {ERR_REASON(PEM_R_CIPHER_IS_NULL) , "cipher is null"},
85 {ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY), "error converting private key"},
86 {ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB), "expecting private key blob"},
87 {ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB), "expecting public key blob"},
88 {ERR_REASON(PEM_R_INCONSISTENT_HEADER) , "inconsistent header"},
89 {ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR), "keyblob header parse error"},
90 {ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT) , "keyblob too short"},
91 {ERR_REASON(PEM_R_NOT_DEK_INFO) , "not dek info"},
92 {ERR_REASON(PEM_R_NOT_ENCRYPTED) , "not encrypted"},
93 {ERR_REASON(PEM_R_NOT_PROC_TYPE) , "not proc type"},
94 {ERR_REASON(PEM_R_NO_START_LINE) , "no start line"},
95 {ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD), "problems getting password"},
96 {ERR_REASON(PEM_R_PUBLIC_KEY_NO_RSA) , "public key no rsa"},
97 {ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT) , "pvk data too short"},
98 {ERR_REASON(PEM_R_PVK_TOO_SHORT) , "pvk too short"},
99 {ERR_REASON(PEM_R_READ_KEY) , "read key"},
100 {ERR_REASON(PEM_R_SHORT_HEADER) , "short header"},
101 {ERR_REASON(PEM_R_UNSUPPORTED_CIPHER) , "unsupported cipher"},
102 {ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION), "unsupported encryption"},
103 {ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS), "unsupported key components"},
104 {0, NULL}
105};
106
107#endif
108
109void
110ERR_load_PEM_strings(void)
111{
112#ifndef OPENSSL_NO_ERR
113 if (ERR_func_error_string(PEM_str_functs[0].error) == NULL) {
114 ERR_load_const_strings(PEM_str_functs);
115 ERR_load_const_strings(PEM_str_reasons);
116 }
117#endif
118}
119LCRYPTO_ALIAS(ERR_load_PEM_strings);
diff --git a/src/lib/libcrypto/pem/pem_info.c b/src/lib/libcrypto/pem/pem_info.c
deleted file mode 100644
index b979c79b33..0000000000
--- a/src/lib/libcrypto/pem/pem_info.c
+++ /dev/null
@@ -1,387 +0,0 @@
1/* $OpenBSD: pem_info.c,v 1.27 2023/07/07 13:40:44 beck Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/opensslconf.h>
63
64#include <openssl/buffer.h>
65#include <openssl/err.h>
66#include <openssl/evp.h>
67#include <openssl/objects.h>
68#include <openssl/pem.h>
69#include <openssl/x509.h>
70
71#ifndef OPENSSL_NO_DSA
72#include <openssl/dsa.h>
73#endif
74#ifndef OPENSSL_NO_RSA
75#include <openssl/rsa.h>
76#endif
77
78#include "evp_local.h"
79
80STACK_OF(X509_INFO) *
81PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb,
82 void *u)
83{
84 BIO *b;
85 STACK_OF(X509_INFO) *ret;
86
87 if ((b = BIO_new(BIO_s_file())) == NULL) {
88 PEMerror(ERR_R_BUF_LIB);
89 return (0);
90 }
91 BIO_set_fp(b, fp, BIO_NOCLOSE);
92 ret = PEM_X509_INFO_read_bio(b, sk, cb, u);
93 BIO_free(b);
94 return (ret);
95}
96LCRYPTO_ALIAS(PEM_X509_INFO_read);
97
98STACK_OF(X509_INFO) *
99PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb,
100 void *u)
101{
102 X509_INFO *xi = NULL;
103 char *name = NULL, *header = NULL;
104 void *pp;
105 unsigned char *data = NULL;
106 const unsigned char *p;
107 long len;
108 int ok = 0;
109 int num_in, ptype, raw;
110 STACK_OF(X509_INFO) *ret = sk;
111 d2i_of_void *d2i = NULL;
112
113 if (ret == NULL) {
114 if ((ret = sk_X509_INFO_new_null()) == NULL) {
115 PEMerror(ERR_R_MALLOC_FAILURE);
116 return NULL;
117 }
118 }
119 num_in = sk_X509_INFO_num(ret);
120
121 if ((xi = X509_INFO_new()) == NULL)
122 goto err;
123 for (;;) {
124 raw = 0;
125 ptype = 0;
126 if (!PEM_read_bio(bp, &name, &header, &data, &len)) {
127 if (ERR_GET_REASON(ERR_peek_last_error()) ==
128 PEM_R_NO_START_LINE) {
129 ERR_clear_error();
130 break;
131 }
132 goto err;
133 }
134 if ((strcmp(name, PEM_STRING_X509) == 0) ||
135 (strcmp(name, PEM_STRING_X509_OLD) == 0)) {
136 d2i = (D2I_OF(void))d2i_X509;
137 if (xi->x509 != NULL) {
138 if (!sk_X509_INFO_push(ret, xi))
139 goto err;
140 if ((xi = X509_INFO_new()) == NULL)
141 goto err;
142 }
143 pp = &(xi->x509);
144 } else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) {
145 d2i = (D2I_OF(void))d2i_X509_AUX;
146 if (xi->x509 != NULL) {
147 if (!sk_X509_INFO_push(ret, xi))
148 goto err;
149 if ((xi = X509_INFO_new()) == NULL)
150 goto err;
151 }
152 pp = &(xi->x509);
153 } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) {
154 d2i = (D2I_OF(void))d2i_X509_CRL;
155 if (xi->crl != NULL) {
156 if (!sk_X509_INFO_push(ret, xi))
157 goto err;
158 if ((xi = X509_INFO_new()) == NULL)
159 goto err;
160 }
161 pp = &(xi->crl);
162 } else
163#ifndef OPENSSL_NO_RSA
164 if (strcmp(name, PEM_STRING_RSA) == 0) {
165 d2i = (D2I_OF(void))d2i_RSAPrivateKey;
166 if (xi->x_pkey != NULL) {
167 if (!sk_X509_INFO_push(ret, xi))
168 goto err;
169 if ((xi = X509_INFO_new()) == NULL)
170 goto err;
171 }
172 xi->enc_data = NULL;
173 xi->enc_len = 0;
174 xi->x_pkey = X509_PKEY_new();
175 if (xi->x_pkey == NULL)
176 goto err;
177 ptype = EVP_PKEY_RSA;
178 pp = &xi->x_pkey->dec_pkey;
179 if (strlen(header) > 10) /* assume encrypted */
180 raw = 1;
181 } else
182#endif
183#ifndef OPENSSL_NO_DSA
184 if (strcmp(name, PEM_STRING_DSA) == 0) {
185 d2i = (D2I_OF(void))d2i_DSAPrivateKey;
186 if (xi->x_pkey != NULL) {
187 if (!sk_X509_INFO_push(ret, xi))
188 goto err;
189 if ((xi = X509_INFO_new()) == NULL)
190 goto err;
191 }
192 xi->enc_data = NULL;
193 xi->enc_len = 0;
194 xi->x_pkey = X509_PKEY_new();
195 if (xi->x_pkey == NULL)
196 goto err;
197 ptype = EVP_PKEY_DSA;
198 pp = &xi->x_pkey->dec_pkey;
199 if (strlen(header) > 10) /* assume encrypted */
200 raw = 1;
201 } else
202#endif
203#ifndef OPENSSL_NO_EC
204 if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) {
205 d2i = (D2I_OF(void))d2i_ECPrivateKey;
206 if (xi->x_pkey != NULL) {
207 if (!sk_X509_INFO_push(ret, xi))
208 goto err;
209 if ((xi = X509_INFO_new()) == NULL)
210 goto err;
211 }
212 xi->enc_data = NULL;
213 xi->enc_len = 0;
214 xi->x_pkey = X509_PKEY_new();
215 if (xi->x_pkey == NULL)
216 goto err;
217 ptype = EVP_PKEY_EC;
218 pp = &xi->x_pkey->dec_pkey;
219 if (strlen(header) > 10) /* assume encrypted */
220 raw = 1;
221 } else
222#endif
223 {
224 d2i = NULL;
225 pp = NULL;
226 }
227
228 if (d2i != NULL) {
229 if (!raw) {
230 EVP_CIPHER_INFO cipher;
231
232 if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
233 goto err;
234 if (!PEM_do_header(&cipher, data, &len, cb, u))
235 goto err;
236 p = data;
237 if (ptype) {
238 if (!d2i_PrivateKey(ptype, pp, &p,
239 len)) {
240 PEMerror(ERR_R_ASN1_LIB);
241 goto err;
242 }
243 } else if (d2i(pp, &p, len) == NULL) {
244 PEMerror(ERR_R_ASN1_LIB);
245 goto err;
246 }
247 } else { /* encrypted RSA data */
248 if (!PEM_get_EVP_CIPHER_INFO(header,
249 &xi->enc_cipher))
250 goto err;
251 xi->enc_data = (char *)data;
252 xi->enc_len = (int)len;
253 data = NULL;
254 }
255 } else {
256 /* unknown */
257 }
258 free(name);
259 free(header);
260 free(data);
261 name = NULL;
262 header = NULL;
263 data = NULL;
264 }
265
266 /* if the last one hasn't been pushed yet and there is anything
267 * in it then add it to the stack ...
268 */
269 if ((xi->x509 != NULL) || (xi->crl != NULL) ||
270 (xi->x_pkey != NULL) || (xi->enc_data != NULL)) {
271 if (!sk_X509_INFO_push(ret, xi))
272 goto err;
273 xi = NULL;
274 }
275 ok = 1;
276
277err:
278 if (!ok) {
279 while (sk_X509_INFO_num(ret) > num_in)
280 X509_INFO_free(sk_X509_INFO_pop(ret));
281 if (ret != sk)
282 sk_X509_INFO_free(ret);
283 ret = NULL;
284 }
285 X509_INFO_free(xi);
286 free(name);
287 free(header);
288 free(data);
289
290 return ret;
291}
292LCRYPTO_ALIAS(PEM_X509_INFO_read_bio);
293
294
295/* A TJH addition */
296int
297PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
298 unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
299{
300 EVP_CIPHER_CTX ctx;
301 int i, ret = 0;
302 unsigned char *data = NULL;
303 const char *objstr = NULL;
304 char buf[PEM_BUFSIZE];
305 unsigned char *iv = NULL;
306
307 if (enc != NULL) {
308 objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
309 if (objstr == NULL) {
310 PEMerror(PEM_R_UNSUPPORTED_CIPHER);
311 goto err;
312 }
313 }
314
315 /* now for the fun part ... if we have a private key then
316 * we have to be able to handle a not-yet-decrypted key
317 * being written out correctly ... if it is decrypted or
318 * it is non-encrypted then we use the base code
319 */
320 if (xi->x_pkey != NULL) {
321 if ((xi->enc_data != NULL) && (xi->enc_len > 0) ) {
322 if (enc == NULL) {
323 PEMerror(PEM_R_CIPHER_IS_NULL);
324 goto err;
325 }
326
327 /* copy from weirdo names into more normal things */
328 iv = xi->enc_cipher.iv;
329 data = (unsigned char *)xi->enc_data;
330 i = xi->enc_len;
331
332 /* we take the encryption data from the
333 * internal stuff rather than what the
334 * user has passed us ... as we have to
335 * match exactly for some strange reason
336 */
337 objstr = OBJ_nid2sn(
338 EVP_CIPHER_nid(xi->enc_cipher.cipher));
339 if (objstr == NULL) {
340 PEMerror(PEM_R_UNSUPPORTED_CIPHER);
341 goto err;
342 }
343
344 /* create the right magic header stuff */
345 if (strlen(objstr) + 23 + 2 * enc->iv_len + 13 >
346 sizeof buf) {
347 PEMerror(ASN1_R_BUFFER_TOO_SMALL);
348 goto err;
349 }
350 buf[0] = '\0';
351 PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
352 PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv);
353
354 /* use the normal code to write things out */
355 i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i);
356 if (i <= 0)
357 goto err;
358 } else {
359 /* Add DSA/DH */
360#ifndef OPENSSL_NO_RSA
361 /* normal optionally encrypted stuff */
362 if (PEM_write_bio_RSAPrivateKey(bp,
363 xi->x_pkey->dec_pkey->pkey.rsa,
364 enc, kstr, klen, cb, u) <= 0)
365 goto err;
366#endif
367 }
368 }
369
370 /* if we have a certificate then write it out now */
371 if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0))
372 goto err;
373
374 /* we are ignoring anything else that is loaded into the X509_INFO
375 * structure for the moment ... as I don't need it so I'm not
376 * coding it here and Eric can do it when this makes it into the
377 * base library --tjh
378 */
379
380 ret = 1;
381
382err:
383 explicit_bzero((char *)&ctx, sizeof(ctx));
384 explicit_bzero(buf, PEM_BUFSIZE);
385 return (ret);
386}
387LCRYPTO_ALIAS(PEM_X509_INFO_write_bio);
diff --git a/src/lib/libcrypto/pem/pem_lib.c b/src/lib/libcrypto/pem/pem_lib.c
deleted file mode 100644
index 30db092c3e..0000000000
--- a/src/lib/libcrypto/pem/pem_lib.c
+++ /dev/null
@@ -1,866 +0,0 @@
1/* $OpenBSD: pem_lib.c,v 1.56 2024/02/18 15:44:10 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <ctype.h>
60#include <stdio.h>
61#include <stdlib.h>
62#include <string.h>
63
64#include <openssl/opensslconf.h>
65
66#include <openssl/buffer.h>
67#include <openssl/err.h>
68#include <openssl/evp.h>
69#include <openssl/objects.h>
70#include <openssl/pem.h>
71#include <openssl/pkcs12.h>
72#include <openssl/x509.h>
73
74#ifndef OPENSSL_NO_DES
75#include <openssl/des.h>
76#endif
77
78#include "asn1_local.h"
79#include "evp_local.h"
80
81#define MIN_LENGTH 4
82
83static int load_iv(char **fromp, unsigned char *to, int num);
84static int check_pem(const char *nm, const char *name);
85int pem_check_suffix(const char *pem_str, const char *suffix);
86
87/* XXX LSSL ABI XXX return value and `num' ought to be size_t */
88int
89PEM_def_callback(char *buf, int num, int w, void *key)
90{
91 size_t l;
92 int i;
93 const char *prompt;
94
95 if (num < 0)
96 return -1;
97
98 if (key) {
99 l = strlen(key);
100 if (l > (size_t)num)
101 l = (size_t)num;
102 memcpy(buf, key, l);
103 return (int)l;
104 }
105
106 prompt = EVP_get_pw_prompt();
107 if (prompt == NULL)
108 prompt = "Enter PEM pass phrase:";
109
110 for (;;) {
111 i = EVP_read_pw_string_min(buf, MIN_LENGTH, num, prompt, w);
112 if (i != 0) {
113 PEMerror(PEM_R_PROBLEMS_GETTING_PASSWORD);
114 memset(buf, 0, num);
115 return (-1);
116 }
117 l = strlen(buf);
118 if (l < MIN_LENGTH) {
119 fprintf(stderr, "phrase is too short, "
120 "needs to be at least %zu chars\n",
121 (size_t)MIN_LENGTH);
122 } else
123 break;
124 }
125 return (int)l;
126}
127LCRYPTO_ALIAS(PEM_def_callback);
128
129void
130PEM_proc_type(char *buf, int type)
131{
132 const char *str;
133
134 if (type == PEM_TYPE_ENCRYPTED)
135 str = "ENCRYPTED";
136 else if (type == PEM_TYPE_MIC_CLEAR)
137 str = "MIC-CLEAR";
138 else if (type == PEM_TYPE_MIC_ONLY)
139 str = "MIC-ONLY";
140 else
141 str = "BAD-TYPE";
142
143 strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE);
144 strlcat(buf, str, PEM_BUFSIZE);
145 strlcat(buf, "\n", PEM_BUFSIZE);
146}
147LCRYPTO_ALIAS(PEM_proc_type);
148
149void
150PEM_dek_info(char *buf, const char *type, int len, char *str)
151{
152 static const unsigned char map[17] = "0123456789ABCDEF";
153 long i;
154 int j;
155
156 strlcat(buf, "DEK-Info: ", PEM_BUFSIZE);
157 strlcat(buf, type, PEM_BUFSIZE);
158 strlcat(buf, ",", PEM_BUFSIZE);
159 j = strlen(buf);
160 if (j + (len * 2) + 1 > PEM_BUFSIZE)
161 return;
162 for (i = 0; i < len; i++) {
163 buf[j + i * 2] = map[(str[i] >> 4) & 0x0f];
164 buf[j + i * 2 + 1] = map[(str[i]) & 0x0f];
165 }
166 buf[j + i * 2] = '\n';
167 buf[j + i * 2 + 1] = '\0';
168}
169LCRYPTO_ALIAS(PEM_dek_info);
170
171void *
172PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
173 pem_password_cb *cb, void *u)
174{
175 BIO *b;
176 void *ret;
177
178 if ((b = BIO_new(BIO_s_file())) == NULL) {
179 PEMerror(ERR_R_BUF_LIB);
180 return (0);
181 }
182 BIO_set_fp(b, fp, BIO_NOCLOSE);
183 ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u);
184 BIO_free(b);
185 return (ret);
186}
187LCRYPTO_ALIAS(PEM_ASN1_read);
188
189static int
190check_pem(const char *nm, const char *name)
191{
192 /* Normal matching nm and name */
193 if (!strcmp(nm, name))
194 return 1;
195
196 /* Make PEM_STRING_EVP_PKEY match any private key */
197
198 if (!strcmp(name, PEM_STRING_EVP_PKEY)) {
199 int slen;
200 const EVP_PKEY_ASN1_METHOD *ameth;
201 if (!strcmp(nm, PEM_STRING_PKCS8))
202 return 1;
203 if (!strcmp(nm, PEM_STRING_PKCS8INF))
204 return 1;
205 slen = pem_check_suffix(nm, "PRIVATE KEY");
206 if (slen > 0) {
207 /* NB: ENGINE implementations wont contain
208 * a deprecated old private key decode function
209 * so don't look for them.
210 */
211 ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
212 if (ameth && ameth->old_priv_decode)
213 return 1;
214 }
215 return 0;
216 }
217
218 if (!strcmp(name, PEM_STRING_PARAMETERS)) {
219 int slen;
220 const EVP_PKEY_ASN1_METHOD *ameth;
221 slen = pem_check_suffix(nm, "PARAMETERS");
222 if (slen > 0) {
223 ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
224 if (ameth) {
225 int r;
226 if (ameth->param_decode)
227 r = 1;
228 else
229 r = 0;
230 return r;
231 }
232 }
233 return 0;
234 }
235
236 /* Permit older strings */
237
238 if (!strcmp(nm, PEM_STRING_X509_OLD) &&
239 !strcmp(name, PEM_STRING_X509))
240 return 1;
241
242 if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) &&
243 !strcmp(name, PEM_STRING_X509_REQ))
244 return 1;
245
246 /* Allow normal certs to be read as trusted certs */
247 if (!strcmp(nm, PEM_STRING_X509) &&
248 !strcmp(name, PEM_STRING_X509_TRUSTED))
249 return 1;
250
251 if (!strcmp(nm, PEM_STRING_X509_OLD) &&
252 !strcmp(name, PEM_STRING_X509_TRUSTED))
253 return 1;
254
255 /* Some CAs use PKCS#7 with CERTIFICATE headers */
256 if (!strcmp(nm, PEM_STRING_X509) &&
257 !strcmp(name, PEM_STRING_PKCS7))
258 return 1;
259
260 if (!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
261 !strcmp(name, PEM_STRING_PKCS7))
262 return 1;
263
264#ifndef OPENSSL_NO_CMS
265 if (strcmp(nm, PEM_STRING_X509) == 0 &&
266 strcmp(name, PEM_STRING_CMS) == 0)
267 return 1;
268
269 /* Allow CMS to be read from PKCS#7 headers */
270 if (strcmp(nm, PEM_STRING_PKCS7) == 0 &&
271 strcmp(name, PEM_STRING_CMS) == 0)
272 return 1;
273#endif
274
275 return 0;
276}
277
278int
279PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
280 const char *name, BIO *bp, pem_password_cb *cb, void *u)
281{
282 EVP_CIPHER_INFO cipher;
283 char *nm = NULL, *header = NULL;
284 unsigned char *data = NULL;
285 long len;
286 int ret = 0;
287
288 for (;;) {
289 if (!PEM_read_bio(bp, &nm, &header, &data, &len)) {
290 if (ERR_GET_REASON(ERR_peek_error()) ==
291 PEM_R_NO_START_LINE)
292 ERR_asprintf_error_data("Expecting: %s", name);
293 return 0;
294 }
295 if (check_pem(nm, name))
296 break;
297 free(nm);
298 free(header);
299 free(data);
300 }
301 if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
302 goto err;
303 if (!PEM_do_header(&cipher, data, &len, cb, u))
304 goto err;
305
306 *pdata = data;
307 *plen = len;
308
309 if (pnm)
310 *pnm = nm;
311
312 ret = 1;
313
314err:
315 if (!ret || !pnm)
316 free(nm);
317 free(header);
318 if (!ret)
319 free(data);
320 return ret;
321}
322LCRYPTO_ALIAS(PEM_bytes_read_bio);
323
324int
325PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, void *x,
326 const EVP_CIPHER *enc, unsigned char *kstr, int klen,
327 pem_password_cb *callback, void *u)
328{
329 BIO *b;
330 int ret;
331
332 if ((b = BIO_new(BIO_s_file())) == NULL) {
333 PEMerror(ERR_R_BUF_LIB);
334 return (0);
335 }
336 BIO_set_fp(b, fp, BIO_NOCLOSE);
337 ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u);
338 BIO_free(b);
339 return (ret);
340}
341LCRYPTO_ALIAS(PEM_ASN1_write);
342
343int
344PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x,
345 const EVP_CIPHER *enc, unsigned char *kstr, int klen,
346 pem_password_cb *callback, void *u)
347{
348 EVP_CIPHER_CTX ctx;
349 int dsize = 0, i, j, ret = 0;
350 unsigned char *p, *data = NULL;
351 const char *objstr = NULL;
352 char buf[PEM_BUFSIZE];
353 unsigned char key[EVP_MAX_KEY_LENGTH];
354 unsigned char iv[EVP_MAX_IV_LENGTH];
355
356 if (enc != NULL) {
357 objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
358 if (objstr == NULL) {
359 PEMerror(PEM_R_UNSUPPORTED_CIPHER);
360 goto err;
361 }
362 }
363
364 if ((dsize = i2d(x, NULL)) < 0) {
365 PEMerror(ERR_R_ASN1_LIB);
366 dsize = 0;
367 goto err;
368 }
369 /* dzise + 8 bytes are needed */
370 /* actually it needs the cipher block size extra... */
371 data = malloc(dsize + 20);
372 if (data == NULL) {
373 PEMerror(ERR_R_MALLOC_FAILURE);
374 goto err;
375 }
376 p = data;
377 i = i2d(x, &p);
378
379 if (enc != NULL) {
380 if (kstr == NULL) {
381 if (callback == NULL)
382 klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
383 else
384 klen = (*callback)(buf, PEM_BUFSIZE, 1, u);
385 if (klen <= 0) {
386 PEMerror(PEM_R_READ_KEY);
387 goto err;
388 }
389 kstr = (unsigned char *)buf;
390 }
391 if ((size_t)enc->iv_len > sizeof(iv)) {
392 PEMerror(EVP_R_IV_TOO_LARGE);
393 goto err;
394 }
395 arc4random_buf(iv, enc->iv_len); /* Generate a salt */
396 /* The 'iv' is used as the iv and as a salt. It is
397 * NOT taken from the BytesToKey function */
398 if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1,
399 key, NULL))
400 goto err;
401
402 if (kstr == (unsigned char *)buf)
403 explicit_bzero(buf, PEM_BUFSIZE);
404
405 if (strlen(objstr) + 23 + 2 * enc->iv_len + 13 > sizeof buf) {
406 PEMerror(ASN1_R_BUFFER_TOO_SMALL);
407 goto err;
408 }
409
410 buf[0] = '\0';
411 PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
412 PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv);
413 /* k=strlen(buf); */
414
415 EVP_CIPHER_CTX_legacy_clear(&ctx);
416 ret = 1;
417 if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv) ||
418 !EVP_EncryptUpdate(&ctx, data, &j, data, i) ||
419 !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i))
420 ret = 0;
421 EVP_CIPHER_CTX_cleanup(&ctx);
422 if (ret == 0)
423 goto err;
424 i += j;
425 } else {
426 ret = 1;
427 buf[0] = '\0';
428 }
429 i = PEM_write_bio(bp, name, buf, data, i);
430 if (i <= 0)
431 ret = 0;
432err:
433 explicit_bzero(key, sizeof(key));
434 explicit_bzero(iv, sizeof(iv));
435 explicit_bzero((char *)&ctx, sizeof(ctx));
436 explicit_bzero(buf, PEM_BUFSIZE);
437 freezero(data, (unsigned int)dsize);
438 return (ret);
439}
440LCRYPTO_ALIAS(PEM_ASN1_write_bio);
441
442int
443PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
444 pem_password_cb *callback, void *u)
445{
446 int i, j, o, klen;
447 long len;
448 EVP_CIPHER_CTX ctx;
449 unsigned char key[EVP_MAX_KEY_LENGTH];
450 char buf[PEM_BUFSIZE];
451
452 len = *plen;
453
454 if (cipher->cipher == NULL)
455 return (1);
456 if (callback == NULL)
457 klen = PEM_def_callback(buf, PEM_BUFSIZE, 0, u);
458 else
459 klen = callback(buf, PEM_BUFSIZE, 0, u);
460 if (klen <= 0) {
461 PEMerror(PEM_R_BAD_PASSWORD_READ);
462 return (0);
463 }
464 if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]),
465 (unsigned char *)buf, klen, 1, key, NULL))
466 return 0;
467
468 j = (int)len;
469 EVP_CIPHER_CTX_legacy_clear(&ctx);
470 o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key,
471 &(cipher->iv[0]));
472 if (o)
473 o = EVP_DecryptUpdate(&ctx, data, &i, data, j);
474 if (o)
475 o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j);
476 EVP_CIPHER_CTX_cleanup(&ctx);
477 explicit_bzero((char *)buf, sizeof(buf));
478 explicit_bzero((char *)key, sizeof(key));
479 if (!o) {
480 PEMerror(PEM_R_BAD_DECRYPT);
481 return (0);
482 }
483 *plen = j + i;
484 return (1);
485}
486LCRYPTO_ALIAS(PEM_do_header);
487
488int
489PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
490{
491 const EVP_CIPHER *enc = NULL;
492 char *p, c;
493 char **header_pp = &header;
494
495 cipher->cipher = NULL;
496 if ((header == NULL) || (*header == '\0') || (*header == '\n'))
497 return (1);
498 if (strncmp(header, "Proc-Type: ", 11) != 0) {
499 PEMerror(PEM_R_NOT_PROC_TYPE);
500 return (0);
501 }
502 header += 11;
503 if (*header != '4')
504 return (0);
505 header++;
506 if (*header != ',')
507 return (0);
508 header++;
509 if (strncmp(header, "ENCRYPTED", 9) != 0) {
510 PEMerror(PEM_R_NOT_ENCRYPTED);
511 return (0);
512 }
513 for (; (*header != '\n') && (*header != '\0'); header++)
514 ;
515 if (*header == '\0') {
516 PEMerror(PEM_R_SHORT_HEADER);
517 return (0);
518 }
519 header++;
520 if (strncmp(header, "DEK-Info: ", 10) != 0) {
521 PEMerror(PEM_R_NOT_DEK_INFO);
522 return (0);
523 }
524 header += 10;
525
526 p = header;
527 for (;;) {
528 c= *header;
529 if (!( ((c >= 'A') && (c <= 'Z')) || (c == '-') ||
530 ((c >= '0') && (c <= '9'))))
531 break;
532 header++;
533 }
534 *header = '\0';
535 cipher->cipher = enc = EVP_get_cipherbyname(p);
536 *header = c;
537 header++;
538
539 if (enc == NULL) {
540 PEMerror(PEM_R_UNSUPPORTED_ENCRYPTION);
541 return (0);
542 }
543 if (!load_iv(header_pp, &(cipher->iv[0]), enc->iv_len))
544 return (0);
545
546 return (1);
547}
548LCRYPTO_ALIAS(PEM_get_EVP_CIPHER_INFO);
549
550static int
551load_iv(char **fromp, unsigned char *to, int num)
552{
553 int v, i;
554 char *from;
555
556 from= *fromp;
557 for (i = 0; i < num; i++)
558 to[i] = 0;
559 num *= 2;
560 for (i = 0; i < num; i++) {
561 if ((*from >= '0') && (*from <= '9'))
562 v = *from - '0';
563 else if ((*from >= 'A') && (*from <= 'F'))
564 v = *from - 'A' + 10;
565 else if ((*from >= 'a') && (*from <= 'f'))
566 v = *from - 'a' + 10;
567 else {
568 PEMerror(PEM_R_BAD_IV_CHARS);
569 return (0);
570 }
571 from++;
572 to[i / 2] |= v << (long)((!(i & 1)) * 4);
573 }
574
575 *fromp = from;
576 return (1);
577}
578
579int
580PEM_write(FILE *fp, const char *name, const char *header,
581 const unsigned char *data, long len)
582{
583 BIO *b;
584 int ret;
585
586 if ((b = BIO_new(BIO_s_file())) == NULL) {
587 PEMerror(ERR_R_BUF_LIB);
588 return (0);
589 }
590 BIO_set_fp(b, fp, BIO_NOCLOSE);
591 ret = PEM_write_bio(b, name, header, data, len);
592 BIO_free(b);
593 return (ret);
594}
595LCRYPTO_ALIAS(PEM_write);
596
597int
598PEM_write_bio(BIO *bp, const char *name, const char *header,
599 const unsigned char *data, long len)
600{
601 int nlen, n, i, j, outl;
602 unsigned char *buf = NULL;
603 EVP_ENCODE_CTX ctx;
604 int reason = ERR_R_BUF_LIB;
605
606 EVP_EncodeInit(&ctx);
607 nlen = strlen(name);
608
609 if ((BIO_write(bp, "-----BEGIN ", 11) != 11) ||
610 (BIO_write(bp, name, nlen) != nlen) ||
611 (BIO_write(bp, "-----\n", 6) != 6))
612 goto err;
613
614 if (header != NULL && (i = strlen(header)) > 0) {
615 if ((BIO_write(bp, header, i) != i) ||
616 (BIO_write(bp, "\n", 1) != 1))
617 goto err;
618 }
619
620 buf = reallocarray(NULL, PEM_BUFSIZE, 8);
621 if (buf == NULL) {
622 reason = ERR_R_MALLOC_FAILURE;
623 goto err;
624 }
625
626 i = j = 0;
627 while (len > 0) {
628 n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len);
629 if (!EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n))
630 goto err;
631 if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl))
632 goto err;
633 i += outl;
634 len -= n;
635 j += n;
636 }
637 EVP_EncodeFinal(&ctx, buf, &outl);
638 if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl))
639 goto err;
640 freezero(buf, PEM_BUFSIZE * 8);
641 buf = NULL;
642 if ((BIO_write(bp, "-----END ", 9) != 9) ||
643 (BIO_write(bp, name, nlen) != nlen) ||
644 (BIO_write(bp, "-----\n", 6) != 6))
645 goto err;
646 return (i + outl);
647
648err:
649 freezero(buf, PEM_BUFSIZE * 8);
650 PEMerror(reason);
651 return (0);
652}
653LCRYPTO_ALIAS(PEM_write_bio);
654
655int
656PEM_read(FILE *fp, char **name, char **header, unsigned char **data, long *len)
657{
658 BIO *b;
659 int ret;
660
661 if ((b = BIO_new(BIO_s_file())) == NULL) {
662 PEMerror(ERR_R_BUF_LIB);
663 return (0);
664 }
665 BIO_set_fp(b, fp, BIO_NOCLOSE);
666 ret = PEM_read_bio(b, name, header, data, len);
667 BIO_free(b);
668 return (ret);
669}
670LCRYPTO_ALIAS(PEM_read);
671
672int
673PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
674 long *len)
675{
676 EVP_ENCODE_CTX ctx;
677 int end = 0, i, k, bl = 0, hl = 0, nohead = 0;
678 char buf[256];
679 BUF_MEM *nameB;
680 BUF_MEM *headerB;
681 BUF_MEM *dataB, *tmpB;
682
683 nameB = BUF_MEM_new();
684 headerB = BUF_MEM_new();
685 dataB = BUF_MEM_new();
686 if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) {
687 BUF_MEM_free(nameB);
688 BUF_MEM_free(headerB);
689 BUF_MEM_free(dataB);
690 PEMerror(ERR_R_MALLOC_FAILURE);
691 return (0);
692 }
693
694 buf[254] = '\0';
695 for (;;) {
696 i = BIO_gets(bp, buf, 254);
697
698 if (i <= 0) {
699 PEMerror(PEM_R_NO_START_LINE);
700 goto err;
701 }
702
703 while ((i >= 0) && (buf[i] <= ' '))
704 i--;
705 buf[++i] = '\n';
706 buf[++i] = '\0';
707
708 if (strncmp(buf, "-----BEGIN ", 11) == 0) {
709 i = strlen(&(buf[11]));
710
711 if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0)
712 continue;
713 if (!BUF_MEM_grow(nameB, i + 9)) {
714 PEMerror(ERR_R_MALLOC_FAILURE);
715 goto err;
716 }
717 memcpy(nameB->data, &(buf[11]), i - 6);
718 nameB->data[i - 6] = '\0';
719 break;
720 }
721 }
722 hl = 0;
723 if (!BUF_MEM_grow(headerB, 256)) {
724 PEMerror(ERR_R_MALLOC_FAILURE);
725 goto err;
726 }
727 headerB->data[0] = '\0';
728 for (;;) {
729 i = BIO_gets(bp, buf, 254);
730 if (i <= 0)
731 break;
732
733 while ((i >= 0) && (buf[i] <= ' '))
734 i--;
735 buf[++i] = '\n';
736 buf[++i] = '\0';
737
738 if (buf[0] == '\n')
739 break;
740 if (!BUF_MEM_grow(headerB, hl + i + 9)) {
741 PEMerror(ERR_R_MALLOC_FAILURE);
742 goto err;
743 }
744 if (strncmp(buf, "-----END ", 9) == 0) {
745 nohead = 1;
746 break;
747 }
748 memcpy(&(headerB->data[hl]), buf, i);
749 headerB->data[hl + i] = '\0';
750 hl += i;
751 }
752
753 bl = 0;
754 if (!BUF_MEM_grow(dataB, 1024)) {
755 PEMerror(ERR_R_MALLOC_FAILURE);
756 goto err;
757 }
758 dataB->data[0] = '\0';
759 if (!nohead) {
760 for (;;) {
761 i = BIO_gets(bp, buf, 254);
762 if (i <= 0)
763 break;
764
765 while ((i >= 0) && (buf[i] <= ' '))
766 i--;
767 buf[++i] = '\n';
768 buf[++i] = '\0';
769
770 if (i != 65)
771 end = 1;
772 if (strncmp(buf, "-----END ", 9) == 0)
773 break;
774 if (i > 65)
775 break;
776 if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) {
777 PEMerror(ERR_R_MALLOC_FAILURE);
778 goto err;
779 }
780 memcpy(&(dataB->data[bl]), buf, i);
781 dataB->data[bl + i] = '\0';
782 bl += i;
783 if (end) {
784 buf[0] = '\0';
785 i = BIO_gets(bp, buf, 254);
786 if (i <= 0)
787 break;
788
789 while ((i >= 0) && (buf[i] <= ' '))
790 i--;
791 buf[++i] = '\n';
792 buf[++i] = '\0';
793
794 break;
795 }
796 }
797 } else {
798 tmpB = headerB;
799 headerB = dataB;
800 dataB = tmpB;
801 bl = hl;
802 }
803 i = strlen(nameB->data);
804 if ((strncmp(buf, "-----END ", 9) != 0) ||
805 (strncmp(nameB->data, &(buf[9]), i) != 0) ||
806 (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) {
807 PEMerror(PEM_R_BAD_END_LINE);
808 goto err;
809 }
810
811 EVP_DecodeInit(&ctx);
812 i = EVP_DecodeUpdate(&ctx,
813 (unsigned char *)dataB->data, &bl,
814 (unsigned char *)dataB->data, bl);
815 if (i < 0) {
816 PEMerror(PEM_R_BAD_BASE64_DECODE);
817 goto err;
818 }
819 i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k);
820 if (i < 0) {
821 PEMerror(PEM_R_BAD_BASE64_DECODE);
822 goto err;
823 }
824 bl += k;
825
826 if (bl == 0)
827 goto err;
828 *name = nameB->data;
829 *header = headerB->data;
830 *data = (unsigned char *)dataB->data;
831 *len = bl;
832 free(nameB);
833 free(headerB);
834 free(dataB);
835 return (1);
836
837err:
838 BUF_MEM_free(nameB);
839 BUF_MEM_free(headerB);
840 BUF_MEM_free(dataB);
841 return (0);
842}
843LCRYPTO_ALIAS(PEM_read_bio);
844
845/* Check pem string and return prefix length.
846 * If for example the pem_str == "RSA PRIVATE KEY" and suffix = "PRIVATE KEY"
847 * the return value is 3 for the string "RSA".
848 */
849
850int
851pem_check_suffix(const char *pem_str, const char *suffix)
852{
853 int pem_len = strlen(pem_str);
854 int suffix_len = strlen(suffix);
855 const char *p;
856
857 if (suffix_len + 1 >= pem_len)
858 return 0;
859 p = pem_str + pem_len - suffix_len;
860 if (strcmp(p, suffix))
861 return 0;
862 p--;
863 if (*p != ' ')
864 return 0;
865 return p - pem_str;
866}
diff --git a/src/lib/libcrypto/pem/pem_oth.c b/src/lib/libcrypto/pem/pem_oth.c
deleted file mode 100644
index 2dca978efd..0000000000
--- a/src/lib/libcrypto/pem/pem_oth.c
+++ /dev/null
@@ -1,88 +0,0 @@
1/* $OpenBSD: pem_oth.c,v 1.9 2023/07/07 13:40:44 beck Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60
61#include <openssl/buffer.h>
62#include <openssl/err.h>
63#include <openssl/evp.h>
64#include <openssl/objects.h>
65#include <openssl/pem.h>
66#include <openssl/x509.h>
67
68/* Handle 'other' PEMs: not private keys */
69
70void *
71PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
72 pem_password_cb *cb, void *u)
73{
74 const unsigned char *p = NULL;
75 unsigned char *data = NULL;
76 long len;
77 char *ret = NULL;
78
79 if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u))
80 return NULL;
81 p = data;
82 ret = d2i(x, &p, len);
83 if (ret == NULL)
84 PEMerror(ERR_R_ASN1_LIB);
85 free(data);
86 return (ret);
87}
88LCRYPTO_ALIAS(PEM_ASN1_read_bio);
diff --git a/src/lib/libcrypto/pem/pem_pk8.c b/src/lib/libcrypto/pem/pem_pk8.c
deleted file mode 100644
index 6d0c0cbd57..0000000000
--- a/src/lib/libcrypto/pem/pem_pk8.c
+++ /dev/null
@@ -1,324 +0,0 @@
1/* $OpenBSD: pem_pk8.c,v 1.14 2023/07/07 13:40:44 beck Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/buffer.h>
63#include <openssl/err.h>
64#include <openssl/evp.h>
65#include <openssl/objects.h>
66#include <openssl/pem.h>
67#include <openssl/pkcs12.h>
68#include <openssl/x509.h>
69
70static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid,
71 const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u);
72static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, int nid,
73 const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u);
74
75/* These functions write a private key in PKCS#8 format: it is a "drop in"
76 * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc'
77 * is NULL then it uses the unencrypted private key form. The 'nid' versions
78 * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0.
79 */
80
81int
82PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, char *kstr,
83 int klen, pem_password_cb *cb, void *u)
84{
85 return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
86}
87LCRYPTO_ALIAS(PEM_write_bio_PKCS8PrivateKey_nid);
88
89int
90PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
91 char *kstr, int klen, pem_password_cb *cb, void *u)
92{
93 return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
94}
95LCRYPTO_ALIAS(PEM_write_bio_PKCS8PrivateKey);
96
97int
98i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
99 char *kstr, int klen, pem_password_cb *cb, void *u)
100{
101 return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
102}
103LCRYPTO_ALIAS(i2d_PKCS8PrivateKey_bio);
104
105int
106i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
107 char *kstr, int klen, pem_password_cb *cb, void *u)
108{
109 return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
110}
111LCRYPTO_ALIAS(i2d_PKCS8PrivateKey_nid_bio);
112
113static int
114do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
115 char *kstr, int klen, pem_password_cb *cb, void *u)
116{
117 X509_SIG *p8;
118 PKCS8_PRIV_KEY_INFO *p8inf;
119 char buf[PEM_BUFSIZE];
120 int ret;
121
122 if (!(p8inf = EVP_PKEY2PKCS8(x))) {
123 PEMerror(PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
124 return 0;
125 }
126 if (enc || (nid != -1)) {
127 if (!kstr) {
128 if (!cb)
129 klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
130 else
131 klen = cb(buf, PEM_BUFSIZE, 1, u);
132 if (klen <= 0) {
133 PEMerror(PEM_R_READ_KEY);
134 PKCS8_PRIV_KEY_INFO_free(p8inf);
135 return 0;
136 }
137
138 kstr = buf;
139 }
140 p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
141 if (kstr == buf)
142 explicit_bzero(buf, klen);
143 PKCS8_PRIV_KEY_INFO_free(p8inf);
144 if (isder)
145 ret = i2d_PKCS8_bio(bp, p8);
146 else
147 ret = PEM_write_bio_PKCS8(bp, p8);
148 X509_SIG_free(p8);
149 return ret;
150 } else {
151 if (isder)
152 ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
153 else
154 ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
155 PKCS8_PRIV_KEY_INFO_free(p8inf);
156 return ret;
157 }
158}
159
160EVP_PKEY *
161d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
162{
163 PKCS8_PRIV_KEY_INFO *p8inf = NULL;
164 X509_SIG *p8 = NULL;
165 int klen;
166 EVP_PKEY *ret;
167 char psbuf[PEM_BUFSIZE];
168
169 p8 = d2i_PKCS8_bio(bp, NULL);
170 if (!p8)
171 return NULL;
172 if (cb)
173 klen = cb(psbuf, PEM_BUFSIZE, 0, u);
174 else
175 klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
176 if (klen <= 0) {
177 PEMerror(PEM_R_BAD_PASSWORD_READ);
178 X509_SIG_free(p8);
179 return NULL;
180 }
181 p8inf = PKCS8_decrypt(p8, psbuf, klen);
182 X509_SIG_free(p8);
183 if (!p8inf)
184 return NULL;
185 ret = EVP_PKCS82PKEY(p8inf);
186 PKCS8_PRIV_KEY_INFO_free(p8inf);
187 if (!ret)
188 return NULL;
189 if (x) {
190 EVP_PKEY_free(*x);
191 *x = ret;
192 }
193 return ret;
194}
195LCRYPTO_ALIAS(d2i_PKCS8PrivateKey_bio);
196
197
198int
199i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
200 char *kstr, int klen, pem_password_cb *cb, void *u)
201{
202 return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
203}
204LCRYPTO_ALIAS(i2d_PKCS8PrivateKey_fp);
205
206int
207i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, char *kstr,
208 int klen, pem_password_cb *cb, void *u)
209{
210 return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
211}
212LCRYPTO_ALIAS(i2d_PKCS8PrivateKey_nid_fp);
213
214int
215PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, char *kstr,
216 int klen, pem_password_cb *cb, void *u)
217{
218 return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
219}
220LCRYPTO_ALIAS(PEM_write_PKCS8PrivateKey_nid);
221
222int
223PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
224 char *kstr, int klen, pem_password_cb *cb, void *u)
225{
226 return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
227}
228LCRYPTO_ALIAS(PEM_write_PKCS8PrivateKey);
229
230static int
231do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
232 char *kstr, int klen, pem_password_cb *cb, void *u)
233{
234 BIO *bp;
235 int ret;
236
237 if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
238 PEMerror(ERR_R_BUF_LIB);
239 return (0);
240 }
241 ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
242 BIO_free(bp);
243 return ret;
244}
245
246EVP_PKEY *
247d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
248{
249 BIO *bp;
250 EVP_PKEY *ret;
251
252 if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
253 PEMerror(ERR_R_BUF_LIB);
254 return NULL;
255 }
256 ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
257 BIO_free(bp);
258 return ret;
259}
260LCRYPTO_ALIAS(d2i_PKCS8PrivateKey_fp);
261
262X509_SIG *
263PEM_read_PKCS8(FILE *fp, X509_SIG **x, pem_password_cb *cb, void *u)
264{
265 return PEM_ASN1_read((d2i_of_void *)d2i_X509_SIG, PEM_STRING_PKCS8, fp,
266 (void **)x, cb, u);
267}
268LCRYPTO_ALIAS(PEM_read_PKCS8);
269
270int
271PEM_write_PKCS8(FILE *fp, X509_SIG *x)
272{
273 return PEM_ASN1_write((i2d_of_void *)i2d_X509_SIG, PEM_STRING_PKCS8, fp,
274 x, NULL, NULL, 0, NULL, NULL);
275}
276LCRYPTO_ALIAS(PEM_write_PKCS8);
277
278X509_SIG *
279PEM_read_bio_PKCS8(BIO *bp, X509_SIG **x, pem_password_cb *cb, void *u)
280{
281 return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509_SIG, PEM_STRING_PKCS8, bp,
282 (void **)x, cb, u);
283}
284LCRYPTO_ALIAS(PEM_read_bio_PKCS8);
285
286int
287PEM_write_bio_PKCS8(BIO *bp, X509_SIG *x)
288{
289 return PEM_ASN1_write_bio((i2d_of_void *)i2d_X509_SIG, PEM_STRING_PKCS8, bp,
290 x, NULL, NULL, 0, NULL, NULL);
291}
292LCRYPTO_ALIAS(PEM_write_bio_PKCS8);
293
294PKCS8_PRIV_KEY_INFO *
295PEM_read_PKCS8_PRIV_KEY_INFO(FILE *fp, PKCS8_PRIV_KEY_INFO **x, pem_password_cb *cb, void *u)
296{
297 return PEM_ASN1_read((d2i_of_void *)d2i_PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, fp,
298 (void **)x, cb, u);
299}
300LCRYPTO_ALIAS(PEM_read_PKCS8_PRIV_KEY_INFO);
301
302int
303PEM_write_PKCS8_PRIV_KEY_INFO(FILE *fp, PKCS8_PRIV_KEY_INFO *x)
304{
305 return PEM_ASN1_write((i2d_of_void *)i2d_PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, fp,
306 x, NULL, NULL, 0, NULL, NULL);
307}
308LCRYPTO_ALIAS(PEM_write_PKCS8_PRIV_KEY_INFO);
309
310PKCS8_PRIV_KEY_INFO *
311PEM_read_bio_PKCS8_PRIV_KEY_INFO(BIO *bp, PKCS8_PRIV_KEY_INFO **x, pem_password_cb *cb, void *u)
312{
313 return PEM_ASN1_read_bio((d2i_of_void *)d2i_PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, bp,
314 (void **)x, cb, u);
315}
316LCRYPTO_ALIAS(PEM_read_bio_PKCS8_PRIV_KEY_INFO);
317
318int
319PEM_write_bio_PKCS8_PRIV_KEY_INFO(BIO *bp, PKCS8_PRIV_KEY_INFO *x)
320{
321 return PEM_ASN1_write_bio((i2d_of_void *)i2d_PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, bp,
322 x, NULL, NULL, 0, NULL, NULL);
323}
324LCRYPTO_ALIAS(PEM_write_bio_PKCS8_PRIV_KEY_INFO);
diff --git a/src/lib/libcrypto/pem/pem_pkey.c b/src/lib/libcrypto/pem/pem_pkey.c
deleted file mode 100644
index d7001c83cc..0000000000
--- a/src/lib/libcrypto/pem/pem_pkey.c
+++ /dev/null
@@ -1,263 +0,0 @@
1/* $OpenBSD: pem_pkey.c,v 1.28 2023/11/19 15:46:10 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include <string.h>
61
62#include <openssl/opensslconf.h>
63
64#include <openssl/buffer.h>
65#include <openssl/err.h>
66#include <openssl/evp.h>
67#include <openssl/objects.h>
68#include <openssl/pem.h>
69#include <openssl/pkcs12.h>
70#include <openssl/x509.h>
71
72#include "asn1_local.h"
73#include "evp_local.h"
74
75int pem_check_suffix(const char *pem_str, const char *suffix);
76
77EVP_PKEY *
78PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
79{
80 char *nm = NULL;
81 const unsigned char *p = NULL;
82 unsigned char *data = NULL;
83 long len;
84 int slen;
85 EVP_PKEY *ret = NULL;
86
87 if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY,
88 bp, cb, u))
89 return NULL;
90 p = data;
91
92 if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) {
93 PKCS8_PRIV_KEY_INFO *p8inf;
94 p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
95 if (!p8inf)
96 goto p8err;
97 ret = EVP_PKCS82PKEY(p8inf);
98 if (x) {
99 EVP_PKEY_free(*x);
100 *x = ret;
101 }
102 PKCS8_PRIV_KEY_INFO_free(p8inf);
103 } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) {
104 PKCS8_PRIV_KEY_INFO *p8inf;
105 X509_SIG *p8;
106 int klen;
107 char psbuf[PEM_BUFSIZE];
108 p8 = d2i_X509_SIG(NULL, &p, len);
109 if (!p8)
110 goto p8err;
111 if (cb)
112 klen = cb(psbuf, PEM_BUFSIZE, 0, u);
113 else
114 klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
115 if (klen <= 0) {
116 PEMerror(PEM_R_BAD_PASSWORD_READ);
117 X509_SIG_free(p8);
118 goto err;
119 }
120 p8inf = PKCS8_decrypt(p8, psbuf, klen);
121 X509_SIG_free(p8);
122 if (!p8inf)
123 goto p8err;
124 ret = EVP_PKCS82PKEY(p8inf);
125 if (x) {
126 EVP_PKEY_free(*x);
127 *x = ret;
128 }
129 PKCS8_PRIV_KEY_INFO_free(p8inf);
130 } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) {
131 const EVP_PKEY_ASN1_METHOD *ameth;
132 ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
133 if (!ameth || !ameth->old_priv_decode)
134 goto p8err;
135 ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len);
136 }
137
138p8err:
139 if (ret == NULL)
140 PEMerror(ERR_R_ASN1_LIB);
141err:
142 free(nm);
143 freezero(data, len);
144 return (ret);
145}
146LCRYPTO_ALIAS(PEM_read_bio_PrivateKey);
147
148int
149PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
150 unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
151{
152 if (x->ameth == NULL || x->ameth->priv_encode != NULL)
153 return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
154 (char *)kstr, klen, cb, u);
155
156 return PEM_write_bio_PrivateKey_traditional(bp, x, enc, kstr, klen, cb,
157 u);
158}
159LCRYPTO_ALIAS(PEM_write_bio_PrivateKey);
160
161int
162PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x,
163 const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb,
164 void *u)
165{
166 char pem_str[80];
167
168 (void) snprintf(pem_str, sizeof(pem_str), "%s PRIVATE KEY",
169 x->ameth->pem_str);
170 return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
171 pem_str, bp, x, enc, kstr, klen, cb, u);
172}
173LCRYPTO_ALIAS(PEM_write_bio_PrivateKey_traditional);
174
175EVP_PKEY *
176PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
177{
178 char *nm = NULL;
179 const unsigned char *p = NULL;
180 unsigned char *data = NULL;
181 long len;
182 int slen;
183 EVP_PKEY *ret = NULL;
184
185 if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS,
186 bp, 0, NULL))
187 return NULL;
188 p = data;
189
190 if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0) {
191 ret = EVP_PKEY_new();
192 if (!ret)
193 goto err;
194 if (!EVP_PKEY_set_type_str(ret, nm, slen) ||
195 !ret->ameth->param_decode ||
196 !ret->ameth->param_decode(ret, &p, len)) {
197 EVP_PKEY_free(ret);
198 ret = NULL;
199 goto err;
200 }
201 if (x) {
202 EVP_PKEY_free(*x);
203 *x = ret;
204 }
205 }
206
207err:
208 if (ret == NULL)
209 PEMerror(ERR_R_ASN1_LIB);
210 free(nm);
211 free(data);
212 return (ret);
213}
214LCRYPTO_ALIAS(PEM_read_bio_Parameters);
215
216int
217PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x)
218{
219 char pem_str[80];
220
221 if (!x->ameth || !x->ameth->param_encode)
222 return 0;
223
224 (void) snprintf(pem_str, sizeof(pem_str), "%s PARAMETERS",
225 x->ameth->pem_str);
226 return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode,
227 pem_str, bp, x, NULL, NULL, 0, 0, NULL);
228}
229LCRYPTO_ALIAS(PEM_write_bio_Parameters);
230
231EVP_PKEY *
232PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
233{
234 BIO *b;
235 EVP_PKEY *ret;
236
237 if ((b = BIO_new(BIO_s_file())) == NULL) {
238 PEMerror(ERR_R_BUF_LIB);
239 return (0);
240 }
241 BIO_set_fp(b, fp, BIO_NOCLOSE);
242 ret = PEM_read_bio_PrivateKey(b, x, cb, u);
243 BIO_free(b);
244 return (ret);
245}
246LCRYPTO_ALIAS(PEM_read_PrivateKey);
247
248int
249PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
250 unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
251{
252 BIO *b;
253 int ret;
254
255 if ((b = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
256 PEMerror(ERR_R_BUF_LIB);
257 return 0;
258 }
259 ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
260 BIO_free(b);
261 return ret;
262}
263LCRYPTO_ALIAS(PEM_write_PrivateKey);
diff --git a/src/lib/libcrypto/pem/pem_sign.c b/src/lib/libcrypto/pem/pem_sign.c
deleted file mode 100644
index 461f957445..0000000000
--- a/src/lib/libcrypto/pem/pem_sign.c
+++ /dev/null
@@ -1,108 +0,0 @@
1/* $OpenBSD: pem_sign.c,v 1.15 2023/07/07 13:40:44 beck Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60
61#include <openssl/err.h>
62#include <openssl/evp.h>
63#include <openssl/objects.h>
64#include <openssl/pem.h>
65#include <openssl/x509.h>
66
67int
68PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type)
69{
70 return EVP_DigestInit_ex(ctx, type, NULL);
71}
72LCRYPTO_ALIAS(PEM_SignInit);
73
74int
75PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data,
76 unsigned int count)
77{
78 return EVP_DigestUpdate(ctx, data, count);
79}
80LCRYPTO_ALIAS(PEM_SignUpdate);
81
82int
83PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
84 EVP_PKEY *pkey)
85{
86 unsigned char *m;
87 int i, ret = 0;
88 unsigned int m_len;
89
90 m = malloc(EVP_PKEY_size(pkey) + 2);
91 if (m == NULL) {
92 PEMerror(ERR_R_MALLOC_FAILURE);
93 goto err;
94 }
95
96 if (EVP_SignFinal(ctx, m, &m_len, pkey) <= 0)
97 goto err;
98
99 i = EVP_EncodeBlock(sigret, m, m_len);
100 *siglen = i;
101 ret = 1;
102
103err:
104 /* ctx has been zeroed by EVP_SignFinal() */
105 free(m);
106 return (ret);
107}
108LCRYPTO_ALIAS(PEM_SignFinal);
diff --git a/src/lib/libcrypto/pem/pem_x509.c b/src/lib/libcrypto/pem/pem_x509.c
deleted file mode 100644
index 0016413b51..0000000000
--- a/src/lib/libcrypto/pem/pem_x509.c
+++ /dev/null
@@ -1,98 +0,0 @@
1/* $OpenBSD: pem_x509.c,v 1.9 2023/07/07 13:40:44 beck Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2001.
4 */
5/* ====================================================================
6 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60
61#include <openssl/bio.h>
62#include <openssl/evp.h>
63#include <openssl/pem.h>
64#include <openssl/pkcs7.h>
65#include <openssl/x509.h>
66
67
68X509 *
69PEM_read_X509(FILE *fp, X509 **x, pem_password_cb *cb, void *u)
70{
71 return PEM_ASN1_read((d2i_of_void *)d2i_X509, PEM_STRING_X509, fp,
72 (void **)x, cb, u);
73}
74LCRYPTO_ALIAS(PEM_read_X509);
75
76int
77PEM_write_X509(FILE *fp, X509 *x)
78{
79 return PEM_ASN1_write((i2d_of_void *)i2d_X509, PEM_STRING_X509, fp,
80 x, NULL, NULL, 0, NULL, NULL);
81}
82LCRYPTO_ALIAS(PEM_write_X509);
83
84X509 *
85PEM_read_bio_X509(BIO *bp, X509 **x, pem_password_cb *cb, void *u)
86{
87 return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, bp,
88 (void **)x, cb, u);
89}
90LCRYPTO_ALIAS(PEM_read_bio_X509);
91
92int
93PEM_write_bio_X509(BIO *bp, X509 *x)
94{
95 return PEM_ASN1_write_bio((i2d_of_void *)i2d_X509, PEM_STRING_X509, bp,
96 x, NULL, NULL, 0, NULL, NULL);
97}
98LCRYPTO_ALIAS(PEM_write_bio_X509);
diff --git a/src/lib/libcrypto/pem/pem_xaux.c b/src/lib/libcrypto/pem/pem_xaux.c
deleted file mode 100644
index 5f44a2b5ef..0000000000
--- a/src/lib/libcrypto/pem/pem_xaux.c
+++ /dev/null
@@ -1,98 +0,0 @@
1/* $OpenBSD: pem_xaux.c,v 1.11 2023/07/07 13:40:44 beck Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2001.
4 */
5/* ====================================================================
6 * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60
61#include <openssl/bio.h>
62#include <openssl/evp.h>
63#include <openssl/pem.h>
64#include <openssl/pkcs7.h>
65#include <openssl/x509.h>
66
67
68X509 *
69PEM_read_X509_AUX(FILE *fp, X509 **x, pem_password_cb *cb, void *u)
70{
71 return PEM_ASN1_read((d2i_of_void *)d2i_X509_AUX, PEM_STRING_X509_TRUSTED, fp,
72 (void **)x, cb, u);
73}
74LCRYPTO_ALIAS(PEM_read_X509_AUX);
75
76int
77PEM_write_X509_AUX(FILE *fp, X509 *x)
78{
79 return PEM_ASN1_write((i2d_of_void *)i2d_X509_AUX, PEM_STRING_X509_TRUSTED, fp,
80 x, NULL, NULL, 0, NULL, NULL);
81}
82LCRYPTO_ALIAS(PEM_write_X509_AUX);
83
84X509 *
85PEM_read_bio_X509_AUX(BIO *bp, X509 **x, pem_password_cb *cb, void *u)
86{
87 return PEM_ASN1_read_bio((d2i_of_void *)d2i_X509_AUX, PEM_STRING_X509_TRUSTED, bp,
88 (void **)x, cb, u);
89}
90LCRYPTO_ALIAS(PEM_read_bio_X509_AUX);
91
92int
93PEM_write_bio_X509_AUX(BIO *bp, X509 *x)
94{
95 return PEM_ASN1_write_bio((i2d_of_void *)i2d_X509_AUX, PEM_STRING_X509_TRUSTED, bp,
96 x, NULL, NULL, 0, NULL, NULL);
97}
98LCRYPTO_ALIAS(PEM_write_bio_X509_AUX);
diff --git a/src/lib/libcrypto/pem/pkcs7.lis b/src/lib/libcrypto/pem/pkcs7.lis
deleted file mode 100644
index be90c5d87f..0000000000
--- a/src/lib/libcrypto/pem/pkcs7.lis
+++ /dev/null
@@ -1,22 +0,0 @@
121 0:d=0 hl=2 l= 0 cons: univ: SEQUENCE
2 00 2:d=0 hl=2 l= 9 prim: univ: OBJECT_IDENTIFIER :pkcs-7-signedData
3 21 13:d=0 hl=2 l= 0 cons: cont: 00 # explicit tag
4 21 15:d=0 hl=2 l= 0 cons: univ: SEQUENCE
5 00 17:d=0 hl=2 l= 1 prim: univ: INTEGER # version
6 20 20:d=0 hl=2 l= 0 cons: univ: SET
7 21 22:d=0 hl=2 l= 0 cons: univ: SEQUENCE
8 00 24:d=0 hl=2 l= 9 prim: univ: OBJECT_IDENTIFIER :pkcs-7-data
9 00 35:d=0 hl=2 l= 0 prim: univ: EOC
10 21 37:d=0 hl=2 l= 0 cons: cont: 00 # cert tag
11 20 39:d=0 hl=4 l=545 cons: univ: SEQUENCE
12 20 588:d=0 hl=4 l=524 cons: univ: SEQUENCE
13 00 1116:d=0 hl=2 l= 0 prim: univ: EOC
14 21 1118:d=0 hl=2 l= 0 cons: cont: 01 # crl tag
15 20 1120:d=0 hl=4 l=653 cons: univ: SEQUENCE
16 20 1777:d=0 hl=4 l=285 cons: univ: SEQUENCE
17 00 2066:d=0 hl=2 l= 0 prim: univ: EOC
18 21 2068:d=0 hl=2 l= 0 cons: univ: SET # signers
19 00 2070:d=0 hl=2 l= 0 prim: univ: EOC
20 00 2072:d=0 hl=2 l= 0 prim: univ: EOC
21 00 2074:d=0 hl=2 l= 0 prim: univ: EOC
2200 2076:d=0 hl=2 l= 0 prim: univ: EOC
diff --git a/src/lib/libcrypto/pem/pvkfmt.c b/src/lib/libcrypto/pem/pvkfmt.c
deleted file mode 100644
index 40c9feefe5..0000000000
--- a/src/lib/libcrypto/pem/pvkfmt.c
+++ /dev/null
@@ -1,944 +0,0 @@
1/* $OpenBSD: pvkfmt.c,v 1.28 2024/02/18 15:45:42 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2005.
4 */
5/* ====================================================================
6 * Copyright (c) 2005 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59/* Support for PVK format keys and related structures (such a PUBLICKEYBLOB
60 * and PRIVATEKEYBLOB).
61 */
62
63#include <stdlib.h>
64#include <string.h>
65
66#include <openssl/opensslconf.h>
67
68#include <openssl/bn.h>
69#include <openssl/err.h>
70#include <openssl/pem.h>
71
72#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
73#include <openssl/dsa.h>
74#include <openssl/rsa.h>
75
76#include "bn_local.h"
77#include "dsa_local.h"
78#include "evp_local.h"
79#include "rsa_local.h"
80
81/* Utility function: read a DWORD (4 byte unsigned integer) in little endian
82 * format
83 */
84
85static unsigned int
86read_ledword(const unsigned char **in)
87{
88 const unsigned char *p = *in;
89 unsigned int ret;
90
91 ret = *p++;
92 ret |= (*p++ << 8);
93 ret |= (*p++ << 16);
94 ret |= (*p++ << 24);
95 *in = p;
96 return ret;
97}
98
99/* Read a BIGNUM in little endian format. The docs say that this should take up
100 * bitlen/8 bytes.
101 */
102
103static int
104read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
105{
106 const unsigned char *p;
107 unsigned char *tmpbuf, *q;
108 unsigned int i;
109
110 p = *in + nbyte - 1;
111 tmpbuf = malloc(nbyte);
112 if (!tmpbuf)
113 return 0;
114 q = tmpbuf;
115 for (i = 0; i < nbyte; i++)
116 *q++ = *p--;
117 *r = BN_bin2bn(tmpbuf, nbyte, NULL);
118 free(tmpbuf);
119 if (*r) {
120 *in += nbyte;
121 return 1;
122 } else
123 return 0;
124}
125
126
127/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */
128
129#define MS_PUBLICKEYBLOB 0x6
130#define MS_PRIVATEKEYBLOB 0x7
131#define MS_RSA1MAGIC 0x31415352L
132#define MS_RSA2MAGIC 0x32415352L
133#define MS_DSS1MAGIC 0x31535344L
134#define MS_DSS2MAGIC 0x32535344L
135
136#define MS_KEYALG_RSA_KEYX 0xa400
137#define MS_KEYALG_DSS_SIGN 0x2200
138
139#define MS_KEYTYPE_KEYX 0x1
140#define MS_KEYTYPE_SIGN 0x2
141
142/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */
143#define MS_PVKMAGIC 0xb0b5f11eL
144/* Salt length for PVK files */
145#define PVK_SALTLEN 0x10
146
147static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
148 unsigned int bitlen, int ispub);
149static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
150 unsigned int bitlen, int ispub);
151
152static int
153do_blob_header(const unsigned char **in, unsigned int length,
154 unsigned int *pmagic, unsigned int *pbitlen, int *pisdss, int *pispub)
155{
156 const unsigned char *p = *in;
157
158 if (length < 16)
159 return 0;
160 /* bType */
161 if (*p == MS_PUBLICKEYBLOB) {
162 if (*pispub == 0) {
163 PEMerror(PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
164 return 0;
165 }
166 *pispub = 1;
167 } else if (*p == MS_PRIVATEKEYBLOB) {
168 if (*pispub == 1) {
169 PEMerror(PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
170 return 0;
171 }
172 *pispub = 0;
173 } else
174 return 0;
175 p++;
176 /* Version */
177 if (*p++ != 0x2) {
178 PEMerror(PEM_R_BAD_VERSION_NUMBER);
179 return 0;
180 }
181 /* Ignore reserved, aiKeyAlg */
182 p += 6;
183 *pmagic = read_ledword(&p);
184 *pbitlen = read_ledword(&p);
185 if (*pbitlen > 65536) {
186 PEMerror(PEM_R_INCONSISTENT_HEADER);
187 return 0;
188 }
189 *pisdss = 0;
190 switch (*pmagic) {
191
192 case MS_DSS1MAGIC:
193 *pisdss = 1;
194 case MS_RSA1MAGIC:
195 if (*pispub == 0) {
196 PEMerror(PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
197 return 0;
198 }
199 break;
200
201 case MS_DSS2MAGIC:
202 *pisdss = 1;
203 case MS_RSA2MAGIC:
204 if (*pispub == 1) {
205 PEMerror(PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
206 return 0;
207 }
208 break;
209
210 default:
211 PEMerror(PEM_R_BAD_MAGIC_NUMBER);
212 return -1;
213 }
214 *in = p;
215 return 1;
216}
217
218static unsigned int
219blob_length(unsigned bitlen, int isdss, int ispub)
220{
221 unsigned int nbyte, hnbyte;
222
223 nbyte = (bitlen + 7) >> 3;
224 hnbyte = (bitlen + 15) >> 4;
225 if (isdss) {
226
227 /* Expected length: 20 for q + 3 components bitlen each + 24
228 * for seed structure.
229 */
230 if (ispub)
231 return 44 + 3 * nbyte;
232 /* Expected length: 20 for q, priv, 2 bitlen components + 24
233 * for seed structure.
234 */
235 else
236 return 64 + 2 * nbyte;
237 } else {
238 /* Expected length: 4 for 'e' + 'n' */
239 if (ispub)
240 return 4 + nbyte;
241 else
242 /* Expected length: 4 for 'e' and 7 other components.
243 * 2 components are bitlen size, 5 are bitlen/2
244 */
245 return 4 + 2*nbyte + 5*hnbyte;
246 }
247
248}
249
250static EVP_PKEY *
251do_b2i(const unsigned char **in, unsigned int length, int ispub)
252{
253 const unsigned char *p = *in;
254 unsigned int bitlen, magic;
255 int isdss;
256
257 if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) {
258 PEMerror(PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
259 return NULL;
260 }
261 length -= 16;
262 if (length < blob_length(bitlen, isdss, ispub)) {
263 PEMerror(PEM_R_KEYBLOB_TOO_SHORT);
264 return NULL;
265 }
266 if (isdss)
267 return b2i_dss(&p, length, bitlen, ispub);
268 else
269 return b2i_rsa(&p, length, bitlen, ispub);
270}
271
272static EVP_PKEY *
273do_b2i_bio(BIO *in, int ispub)
274{
275 const unsigned char *p;
276 unsigned char hdr_buf[16], *buf = NULL;
277 unsigned int bitlen, magic, length;
278 int isdss;
279 EVP_PKEY *ret = NULL;
280
281 if (BIO_read(in, hdr_buf, 16) != 16) {
282 PEMerror(PEM_R_KEYBLOB_TOO_SHORT);
283 return NULL;
284 }
285 p = hdr_buf;
286 if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
287 return NULL;
288
289 length = blob_length(bitlen, isdss, ispub);
290 buf = malloc(length);
291 if (!buf) {
292 PEMerror(ERR_R_MALLOC_FAILURE);
293 goto err;
294 }
295 p = buf;
296 if (BIO_read(in, buf, length) != (int)length) {
297 PEMerror(PEM_R_KEYBLOB_TOO_SHORT);
298 goto err;
299 }
300
301 if (isdss)
302 ret = b2i_dss(&p, length, bitlen, ispub);
303 else
304 ret = b2i_rsa(&p, length, bitlen, ispub);
305
306 err:
307 free(buf);
308 return ret;
309}
310
311static EVP_PKEY *
312b2i_dss(const unsigned char **in, unsigned int length, unsigned int bitlen,
313 int ispub)
314{
315 const unsigned char *p = *in;
316 EVP_PKEY *ret = NULL;
317 DSA *dsa = NULL;
318 BN_CTX *ctx = NULL;
319 unsigned int nbyte;
320
321 nbyte = (bitlen + 7) >> 3;
322
323 dsa = DSA_new();
324 ret = EVP_PKEY_new();
325 if (!dsa || !ret)
326 goto err;
327 if (!read_lebn(&p, nbyte, &dsa->p))
328 goto err;
329 if (!read_lebn(&p, 20, &dsa->q))
330 goto err;
331 if (!read_lebn(&p, nbyte, &dsa->g))
332 goto err;
333 if (ispub) {
334 if (!read_lebn(&p, nbyte, &dsa->pub_key))
335 goto err;
336 } else {
337 if (!read_lebn(&p, 20, &dsa->priv_key))
338 goto err;
339 /* Calculate public key */
340 if (!(dsa->pub_key = BN_new()))
341 goto err;
342 if (!(ctx = BN_CTX_new()))
343 goto err;
344 if (!BN_mod_exp_ct(dsa->pub_key, dsa->g,
345 dsa->priv_key, dsa->p, ctx))
346 goto err;
347 BN_CTX_free(ctx);
348 }
349
350 EVP_PKEY_set1_DSA(ret, dsa);
351 DSA_free(dsa);
352 *in = p;
353 return ret;
354
355 err:
356 PEMerror(ERR_R_MALLOC_FAILURE);
357 DSA_free(dsa);
358 EVP_PKEY_free(ret);
359 BN_CTX_free(ctx);
360 return NULL;
361}
362
363static EVP_PKEY *
364b2i_rsa(const unsigned char **in, unsigned int length, unsigned int bitlen,
365 int ispub)
366{
367 const unsigned char *p = *in;
368 EVP_PKEY *ret = NULL;
369 RSA *rsa = NULL;
370 unsigned int nbyte, hnbyte;
371
372 nbyte = (bitlen + 7) >> 3;
373 hnbyte = (bitlen + 15) >> 4;
374 rsa = RSA_new();
375 ret = EVP_PKEY_new();
376 if (!rsa || !ret)
377 goto err;
378 rsa->e = BN_new();
379 if (!rsa->e)
380 goto err;
381 if (!BN_set_word(rsa->e, read_ledword(&p)))
382 goto err;
383 if (!read_lebn(&p, nbyte, &rsa->n))
384 goto err;
385 if (!ispub) {
386 if (!read_lebn(&p, hnbyte, &rsa->p))
387 goto err;
388 if (!read_lebn(&p, hnbyte, &rsa->q))
389 goto err;
390 if (!read_lebn(&p, hnbyte, &rsa->dmp1))
391 goto err;
392 if (!read_lebn(&p, hnbyte, &rsa->dmq1))
393 goto err;
394 if (!read_lebn(&p, hnbyte, &rsa->iqmp))
395 goto err;
396 if (!read_lebn(&p, nbyte, &rsa->d))
397 goto err;
398 }
399
400 EVP_PKEY_set1_RSA(ret, rsa);
401 RSA_free(rsa);
402 *in = p;
403 return ret;
404
405 err:
406 PEMerror(ERR_R_MALLOC_FAILURE);
407 RSA_free(rsa);
408 EVP_PKEY_free(ret);
409 return NULL;
410}
411
412EVP_PKEY *
413b2i_PrivateKey(const unsigned char **in, long length)
414{
415 return do_b2i(in, length, 0);
416}
417LCRYPTO_ALIAS(b2i_PrivateKey);
418
419EVP_PKEY *
420b2i_PublicKey(const unsigned char **in, long length)
421{
422 return do_b2i(in, length, 1);
423}
424LCRYPTO_ALIAS(b2i_PublicKey);
425
426EVP_PKEY *
427b2i_PrivateKey_bio(BIO *in)
428{
429 return do_b2i_bio(in, 0);
430}
431LCRYPTO_ALIAS(b2i_PrivateKey_bio);
432
433EVP_PKEY *
434b2i_PublicKey_bio(BIO *in)
435{
436 return do_b2i_bio(in, 1);
437}
438LCRYPTO_ALIAS(b2i_PublicKey_bio);
439
440static void
441write_ledword(unsigned char **out, unsigned int dw)
442{
443 unsigned char *p = *out;
444
445 *p++ = dw & 0xff;
446 *p++ = (dw >> 8) & 0xff;
447 *p++ = (dw >> 16) & 0xff;
448 *p++ = (dw >> 24) & 0xff;
449 *out = p;
450}
451
452static void
453write_lebn(unsigned char **out, const BIGNUM *bn, int len)
454{
455 int nb, i;
456 unsigned char *p = *out, *q, c;
457
458 nb = BN_num_bytes(bn);
459 BN_bn2bin(bn, p);
460 q = p + nb - 1;
461 /* In place byte order reversal */
462 for (i = 0; i < nb / 2; i++) {
463 c = *p;
464 *p++ = *q;
465 *q-- = c;
466 }
467 *out += nb;
468 /* Pad with zeroes if we have to */
469 if (len > 0) {
470 len -= nb;
471 if (len > 0) {
472 memset(*out, 0, len);
473 *out += len;
474 }
475 }
476}
477
478
479static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic);
480static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic);
481
482static void write_rsa(unsigned char **out, RSA *rsa, int ispub);
483static void write_dsa(unsigned char **out, DSA *dsa, int ispub);
484
485static int
486do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub)
487{
488 unsigned char *p;
489 unsigned int bitlen, magic = 0, keyalg;
490 int outlen, noinc = 0;
491
492 if (pk->type == EVP_PKEY_DSA) {
493 bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic);
494 keyalg = MS_KEYALG_DSS_SIGN;
495 } else if (pk->type == EVP_PKEY_RSA) {
496 bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic);
497 keyalg = MS_KEYALG_RSA_KEYX;
498 } else
499 return -1;
500 if (bitlen == 0)
501 return -1;
502 outlen = 16 + blob_length(bitlen,
503 keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub);
504 if (out == NULL)
505 return outlen;
506 if (*out)
507 p = *out;
508 else {
509 p = malloc(outlen);
510 if (!p)
511 return -1;
512 *out = p;
513 noinc = 1;
514 }
515 if (ispub)
516 *p++ = MS_PUBLICKEYBLOB;
517 else
518 *p++ = MS_PRIVATEKEYBLOB;
519 *p++ = 0x2;
520 *p++ = 0;
521 *p++ = 0;
522 write_ledword(&p, keyalg);
523 write_ledword(&p, magic);
524 write_ledword(&p, bitlen);
525 if (keyalg == MS_KEYALG_DSS_SIGN)
526 write_dsa(&p, pk->pkey.dsa, ispub);
527 else
528 write_rsa(&p, pk->pkey.rsa, ispub);
529 if (!noinc)
530 *out += outlen;
531 return outlen;
532}
533
534static int
535do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub)
536{
537 unsigned char *tmp = NULL;
538 int outlen, wrlen;
539
540 outlen = do_i2b(&tmp, pk, ispub);
541 if (outlen < 0)
542 return -1;
543 wrlen = BIO_write(out, tmp, outlen);
544 free(tmp);
545 if (wrlen == outlen)
546 return outlen;
547 return -1;
548}
549
550static int
551check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic)
552{
553 int bitlen;
554
555 bitlen = BN_num_bits(dsa->p);
556 if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160) ||
557 (BN_num_bits(dsa->g) > bitlen))
558 goto err;
559 if (ispub) {
560 if (BN_num_bits(dsa->pub_key) > bitlen)
561 goto err;
562 *pmagic = MS_DSS1MAGIC;
563 } else {
564 if (BN_num_bits(dsa->priv_key) > 160)
565 goto err;
566 *pmagic = MS_DSS2MAGIC;
567 }
568
569 return bitlen;
570
571 err:
572 PEMerror(PEM_R_UNSUPPORTED_KEY_COMPONENTS);
573 return 0;
574}
575
576static int
577check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic)
578{
579 int nbyte, hnbyte, bitlen;
580
581 if (BN_num_bits(rsa->e) > 32)
582 goto err;
583 bitlen = BN_num_bits(rsa->n);
584 nbyte = BN_num_bytes(rsa->n);
585 hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
586 if (ispub) {
587 *pmagic = MS_RSA1MAGIC;
588 return bitlen;
589 } else {
590 *pmagic = MS_RSA2MAGIC;
591 /* For private key each component must fit within nbyte or
592 * hnbyte.
593 */
594 if (BN_num_bytes(rsa->d) > nbyte)
595 goto err;
596 if ((BN_num_bytes(rsa->iqmp) > hnbyte) ||
597 (BN_num_bytes(rsa->p) > hnbyte) ||
598 (BN_num_bytes(rsa->q) > hnbyte) ||
599 (BN_num_bytes(rsa->dmp1) > hnbyte) ||
600 (BN_num_bytes(rsa->dmq1) > hnbyte))
601 goto err;
602 }
603 return bitlen;
604
605 err:
606 PEMerror(PEM_R_UNSUPPORTED_KEY_COMPONENTS);
607 return 0;
608}
609
610static void
611write_rsa(unsigned char **out, RSA *rsa, int ispub)
612{
613 int nbyte, hnbyte;
614
615 nbyte = BN_num_bytes(rsa->n);
616 hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
617 write_lebn(out, rsa->e, 4);
618 write_lebn(out, rsa->n, -1);
619 if (ispub)
620 return;
621 write_lebn(out, rsa->p, hnbyte);
622 write_lebn(out, rsa->q, hnbyte);
623 write_lebn(out, rsa->dmp1, hnbyte);
624 write_lebn(out, rsa->dmq1, hnbyte);
625 write_lebn(out, rsa->iqmp, hnbyte);
626 write_lebn(out, rsa->d, nbyte);
627}
628
629static void
630write_dsa(unsigned char **out, DSA *dsa, int ispub)
631{
632 int nbyte;
633
634 nbyte = BN_num_bytes(dsa->p);
635 write_lebn(out, dsa->p, nbyte);
636 write_lebn(out, dsa->q, 20);
637 write_lebn(out, dsa->g, nbyte);
638 if (ispub)
639 write_lebn(out, dsa->pub_key, nbyte);
640 else
641 write_lebn(out, dsa->priv_key, 20);
642 /* Set "invalid" for seed structure values */
643 memset(*out, 0xff, 24);
644 *out += 24;
645 return;
646}
647
648int
649i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk)
650{
651 return do_i2b_bio(out, pk, 0);
652}
653LCRYPTO_ALIAS(i2b_PrivateKey_bio);
654
655int
656i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk)
657{
658 return do_i2b_bio(out, pk, 1);
659}
660LCRYPTO_ALIAS(i2b_PublicKey_bio);
661
662#ifndef OPENSSL_NO_RC4
663
664static int
665do_PVK_header(const unsigned char **in, unsigned int length, int skip_magic,
666 unsigned int *psaltlen, unsigned int *pkeylen)
667{
668 const unsigned char *p = *in;
669 unsigned int pvk_magic, is_encrypted;
670
671 if (skip_magic) {
672 if (length < 20) {
673 PEMerror(PEM_R_PVK_TOO_SHORT);
674 return 0;
675 }
676 length -= 20;
677 } else {
678 if (length < 24) {
679 PEMerror(PEM_R_PVK_TOO_SHORT);
680 return 0;
681 }
682 length -= 24;
683 pvk_magic = read_ledword(&p);
684 if (pvk_magic != MS_PVKMAGIC) {
685 PEMerror(PEM_R_BAD_MAGIC_NUMBER);
686 return 0;
687 }
688 }
689 /* Skip reserved */
690 p += 4;
691 /*keytype = */read_ledword(&p);
692 is_encrypted = read_ledword(&p);
693 *psaltlen = read_ledword(&p);
694 *pkeylen = read_ledword(&p);
695 if (*psaltlen > 65536 || *pkeylen > 65536) {
696 PEMerror(PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
697 return 0;
698 }
699
700 if (is_encrypted && !*psaltlen) {
701 PEMerror(PEM_R_INCONSISTENT_HEADER);
702 return 0;
703 }
704
705 *in = p;
706 return 1;
707}
708
709static int
710derive_pvk_key(unsigned char *key, const unsigned char *salt,
711 unsigned int saltlen, const unsigned char *pass, int passlen)
712{
713 EVP_MD_CTX mctx;
714 int rv = 1;
715
716 EVP_MD_CTX_legacy_clear(&mctx);
717 if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL) ||
718 !EVP_DigestUpdate(&mctx, salt, saltlen) ||
719 !EVP_DigestUpdate(&mctx, pass, passlen) ||
720 !EVP_DigestFinal_ex(&mctx, key, NULL))
721 rv = 0;
722
723 EVP_MD_CTX_cleanup(&mctx);
724 return rv;
725}
726
727static EVP_PKEY *
728do_PVK_body(const unsigned char **in, unsigned int saltlen,
729 unsigned int keylen, pem_password_cb *cb, void *u)
730{
731 EVP_PKEY *ret = NULL;
732 const unsigned char *p = *in;
733 unsigned int magic;
734 unsigned char *enctmp = NULL, *q;
735 EVP_CIPHER_CTX *cctx = NULL;
736
737 if ((cctx = EVP_CIPHER_CTX_new()) == NULL) {
738 PEMerror(ERR_R_MALLOC_FAILURE);
739 goto err;
740 }
741 if (saltlen) {
742 char psbuf[PEM_BUFSIZE];
743 unsigned char keybuf[20];
744 int enctmplen, inlen;
745
746 if (cb)
747 inlen = cb(psbuf, PEM_BUFSIZE, 0, u);
748 else
749 inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
750 if (inlen <= 0) {
751 PEMerror(PEM_R_BAD_PASSWORD_READ);
752 goto err;
753 }
754 enctmp = malloc(keylen + 8);
755 if (!enctmp) {
756 PEMerror(ERR_R_MALLOC_FAILURE);
757 goto err;
758 }
759 if (!derive_pvk_key(keybuf, p, saltlen, (unsigned char *)psbuf,
760 inlen)) {
761 goto err;
762 }
763 p += saltlen;
764 /* Copy BLOBHEADER across, decrypt rest */
765 memcpy(enctmp, p, 8);
766 p += 8;
767 if (keylen < 8) {
768 PEMerror(PEM_R_PVK_TOO_SHORT);
769 goto err;
770 }
771 inlen = keylen - 8;
772 q = enctmp + 8;
773 if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
774 goto err;
775 if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen))
776 goto err;
777 if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, &enctmplen))
778 goto err;
779 magic = read_ledword((const unsigned char **)&q);
780 if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
781 q = enctmp + 8;
782 memset(keybuf + 5, 0, 11);
783 if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf,
784 NULL))
785 goto err;
786 explicit_bzero(keybuf, 20);
787 if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen))
788 goto err;
789 if (!EVP_DecryptFinal_ex(cctx, q + enctmplen,
790 &enctmplen))
791 goto err;
792 magic = read_ledword((const unsigned char **)&q);
793 if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
794 PEMerror(PEM_R_BAD_DECRYPT);
795 goto err;
796 }
797 } else
798 explicit_bzero(keybuf, 20);
799 p = enctmp;
800 }
801
802 ret = b2i_PrivateKey(&p, keylen);
803
804 err:
805 EVP_CIPHER_CTX_free(cctx);
806 if (enctmp && saltlen)
807 free(enctmp);
808 return ret;
809}
810
811
812EVP_PKEY *
813b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
814{
815 unsigned char pvk_hdr[24], *buf = NULL;
816 const unsigned char *p;
817 size_t buflen;
818 EVP_PKEY *ret = NULL;
819 unsigned int saltlen, keylen;
820
821 if (BIO_read(in, pvk_hdr, 24) != 24) {
822 PEMerror(PEM_R_PVK_DATA_TOO_SHORT);
823 return NULL;
824 }
825 p = pvk_hdr;
826
827 if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen))
828 return 0;
829 buflen = keylen + saltlen;
830 buf = malloc(buflen);
831 if (!buf) {
832 PEMerror(ERR_R_MALLOC_FAILURE);
833 return 0;
834 }
835 p = buf;
836 if (BIO_read(in, buf, buflen) != buflen) {
837 PEMerror(PEM_R_PVK_DATA_TOO_SHORT);
838 goto err;
839 }
840 ret = do_PVK_body(&p, saltlen, keylen, cb, u);
841
842 err:
843 freezero(buf, buflen);
844 return ret;
845}
846LCRYPTO_ALIAS(b2i_PVK_bio);
847
848static int
849i2b_PVK(unsigned char **out, EVP_PKEY*pk, int enclevel, pem_password_cb *cb,
850 void *u)
851{
852 int outlen = 24, pklen;
853 unsigned char *p = NULL, *start = NULL, *salt = NULL;
854 EVP_CIPHER_CTX *cctx = NULL;
855
856 if ((cctx = EVP_CIPHER_CTX_new()) == NULL) {
857 PEMerror(ERR_R_MALLOC_FAILURE);
858 goto err;
859 }
860 if (enclevel != 0)
861 outlen += PVK_SALTLEN;
862 pklen = do_i2b(NULL, pk, 0);
863 if (pklen < 0)
864 goto err;
865 outlen += pklen;
866 start = p = malloc(outlen);
867 if (!p) {
868 PEMerror(ERR_R_MALLOC_FAILURE);
869 goto err;
870 }
871
872 write_ledword(&p, MS_PVKMAGIC);
873 write_ledword(&p, 0);
874 if (pk->type == EVP_PKEY_DSA)
875 write_ledword(&p, MS_KEYTYPE_SIGN);
876 else
877 write_ledword(&p, MS_KEYTYPE_KEYX);
878 write_ledword(&p, enclevel ? 1 : 0);
879 write_ledword(&p, enclevel ? PVK_SALTLEN : 0);
880 write_ledword(&p, pklen);
881 if (enclevel != 0) {
882 arc4random_buf(p, PVK_SALTLEN);
883 salt = p;
884 p += PVK_SALTLEN;
885 }
886 do_i2b(&p, pk, 0);
887 if (enclevel != 0) {
888 char psbuf[PEM_BUFSIZE];
889 unsigned char keybuf[20];
890 int enctmplen, inlen;
891 if (cb)
892 inlen = cb(psbuf, PEM_BUFSIZE, 1, u);
893 else
894 inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u);
895 if (inlen <= 0) {
896 PEMerror(PEM_R_BAD_PASSWORD_READ);
897 goto err;
898 }
899 if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
900 (unsigned char *)psbuf, inlen))
901 goto err;
902 if (enclevel == 1)
903 memset(keybuf + 5, 0, 11);
904 p = salt + PVK_SALTLEN + 8;
905 if (!EVP_EncryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
906 goto err;
907 explicit_bzero(keybuf, 20);
908 if (!EVP_EncryptUpdate(cctx, p, &enctmplen, p, pklen - 8))
909 goto err;
910 if (!EVP_EncryptFinal_ex(cctx, p + enctmplen, &enctmplen))
911 goto err;
912 }
913 EVP_CIPHER_CTX_free(cctx);
914 *out = start;
915 return outlen;
916
917 err:
918 EVP_CIPHER_CTX_free(cctx);
919 free(start);
920 return -1;
921}
922
923int
924i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, pem_password_cb *cb, void *u)
925{
926 unsigned char *tmp = NULL;
927 int outlen, wrlen;
928
929 outlen = i2b_PVK(&tmp, pk, enclevel, cb, u);
930 if (outlen < 0)
931 return -1;
932 wrlen = BIO_write(out, tmp, outlen);
933 free(tmp);
934 if (wrlen != outlen) {
935 PEMerror(PEM_R_BIO_WRITE_FAILURE);
936 return -1;
937 }
938 return outlen;
939}
940LCRYPTO_ALIAS(i2b_PVK_bio);
941
942#endif
943
944#endif