summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pem/pem_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/pem/pem_lib.c')
-rw-r--r--src/lib/libcrypto/pem/pem_lib.c100
1 files changed, 85 insertions, 15 deletions
diff --git a/src/lib/libcrypto/pem/pem_lib.c b/src/lib/libcrypto/pem/pem_lib.c
index cbafefe416..42e4861bc1 100644
--- a/src/lib/libcrypto/pem/pem_lib.c
+++ b/src/lib/libcrypto/pem/pem_lib.c
@@ -57,6 +57,7 @@
57 */ 57 */
58 58
59#include <stdio.h> 59#include <stdio.h>
60#include <ctype.h>
60#include "cryptlib.h" 61#include "cryptlib.h"
61#include <openssl/buffer.h> 62#include <openssl/buffer.h>
62#include <openssl/objects.h> 63#include <openssl/objects.h>
@@ -65,9 +66,13 @@
65#include <openssl/x509.h> 66#include <openssl/x509.h>
66#include <openssl/pem.h> 67#include <openssl/pem.h>
67#include <openssl/pkcs12.h> 68#include <openssl/pkcs12.h>
69#include "asn1_locl.h"
68#ifndef OPENSSL_NO_DES 70#ifndef OPENSSL_NO_DES
69#include <openssl/des.h> 71#include <openssl/des.h>
70#endif 72#endif
73#ifndef OPENSSL_NO_ENGINE
74#include <openssl/engine.h>
75#endif
71 76
72const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT; 77const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT;
73 78
@@ -75,6 +80,7 @@ const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT;
75 80
76static int load_iv(char **fromp,unsigned char *to, int num); 81static int load_iv(char **fromp,unsigned char *to, int num);
77static int check_pem(const char *nm, const char *name); 82static int check_pem(const char *nm, const char *name);
83int pem_check_suffix(const char *pem_str, const char *suffix);
78 84
79int PEM_def_callback(char *buf, int num, int w, void *key) 85int PEM_def_callback(char *buf, int num, int w, void *key)
80 { 86 {
@@ -99,7 +105,7 @@ int PEM_def_callback(char *buf, int num, int w, void *key)
99 105
100 for (;;) 106 for (;;)
101 { 107 {
102 i=EVP_read_pw_string(buf,num,prompt,w); 108 i=EVP_read_pw_string_min(buf,MIN_LENGTH,num,prompt,w);
103 if (i != 0) 109 if (i != 0)
104 { 110 {
105 PEMerr(PEM_F_PEM_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD); 111 PEMerr(PEM_F_PEM_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD);
@@ -183,20 +189,54 @@ static int check_pem(const char *nm, const char *name)
183 189
184 /* Make PEM_STRING_EVP_PKEY match any private key */ 190 /* Make PEM_STRING_EVP_PKEY match any private key */
185 191
186 if(!strcmp(nm,PEM_STRING_PKCS8) && 192 if(!strcmp(name,PEM_STRING_EVP_PKEY))
187 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; 193 {
188 194 int slen;
189 if(!strcmp(nm,PEM_STRING_PKCS8INF) && 195 const EVP_PKEY_ASN1_METHOD *ameth;
190 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; 196 if(!strcmp(nm,PEM_STRING_PKCS8))
191 197 return 1;
192 if(!strcmp(nm,PEM_STRING_RSA) && 198 if(!strcmp(nm,PEM_STRING_PKCS8INF))
193 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; 199 return 1;
200 slen = pem_check_suffix(nm, "PRIVATE KEY");
201 if (slen > 0)
202 {
203 /* NB: ENGINE implementations wont contain
204 * a deprecated old private key decode function
205 * so don't look for them.
206 */
207 ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
208 if (ameth && ameth->old_priv_decode)
209 return 1;
210 }
211 return 0;
212 }
194 213
195 if(!strcmp(nm,PEM_STRING_DSA) && 214 if(!strcmp(name,PEM_STRING_PARAMETERS))
196 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; 215 {
216 int slen;
217 const EVP_PKEY_ASN1_METHOD *ameth;
218 slen = pem_check_suffix(nm, "PARAMETERS");
219 if (slen > 0)
220 {
221 ENGINE *e;
222 ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
223 if (ameth)
224 {
225 int r;
226 if (ameth->param_decode)
227 r = 1;
228 else
229 r = 0;
230#ifndef OPENSSL_NO_ENGINE
231 if (e)
232 ENGINE_finish(e);
233#endif
234 return r;
235 }
236 }
237 return 0;
238 }
197 239
198 if(!strcmp(nm,PEM_STRING_ECPRIVATEKEY) &&
199 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
200 /* Permit older strings */ 240 /* Permit older strings */
201 241
202 if(!strcmp(nm,PEM_STRING_X509_OLD) && 242 if(!strcmp(nm,PEM_STRING_X509_OLD) &&
@@ -219,6 +259,14 @@ static int check_pem(const char *nm, const char *name)
219 if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && 259 if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
220 !strcmp(name, PEM_STRING_PKCS7)) return 1; 260 !strcmp(name, PEM_STRING_PKCS7)) return 1;
221 261
262#ifndef OPENSSL_NO_CMS
263 if(!strcmp(nm, PEM_STRING_X509) &&
264 !strcmp(name, PEM_STRING_CMS)) return 1;
265 /* Allow CMS to be read from PKCS#7 headers */
266 if(!strcmp(nm, PEM_STRING_PKCS7) &&
267 !strcmp(name, PEM_STRING_CMS)) return 1;
268#endif
269
222 return 0; 270 return 0;
223} 271}
224 272
@@ -264,7 +312,7 @@ err:
264 312
265#ifndef OPENSSL_NO_FP_API 313#ifndef OPENSSL_NO_FP_API
266int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, 314int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
267 char *x, const EVP_CIPHER *enc, unsigned char *kstr, 315 void *x, const EVP_CIPHER *enc, unsigned char *kstr,
268 int klen, pem_password_cb *callback, void *u) 316 int klen, pem_password_cb *callback, void *u)
269 { 317 {
270 BIO *b; 318 BIO *b;
@@ -283,7 +331,7 @@ int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
283#endif 331#endif
284 332
285int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, 333int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
286 char *x, const EVP_CIPHER *enc, unsigned char *kstr, 334 void *x, const EVP_CIPHER *enc, unsigned char *kstr,
287 int klen, pem_password_cb *callback, void *u) 335 int klen, pem_password_cb *callback, void *u)
288 { 336 {
289 EVP_CIPHER_CTX ctx; 337 EVP_CIPHER_CTX ctx;
@@ -782,3 +830,25 @@ err:
782 BUF_MEM_free(dataB); 830 BUF_MEM_free(dataB);
783 return(0); 831 return(0);
784 } 832 }
833
834/* Check pem string and return prefix length.
835 * If for example the pem_str == "RSA PRIVATE KEY" and suffix = "PRIVATE KEY"
836 * the return value is 3 for the string "RSA".
837 */
838
839int pem_check_suffix(const char *pem_str, const char *suffix)
840 {
841 int pem_len = strlen(pem_str);
842 int suffix_len = strlen(suffix);
843 const char *p;
844 if (suffix_len + 1 >= pem_len)
845 return 0;
846 p = pem_str + pem_len - suffix_len;
847 if (strcmp(p, suffix))
848 return 0;
849 p--;
850 if (*p != ' ')
851 return 0;
852 return p - pem_str;
853 }
854