| Index: openssl/crypto/pem/pem_lib.c
|
| ===================================================================
|
| --- openssl/crypto/pem/pem_lib.c (revision 105093)
|
| +++ openssl/crypto/pem/pem_lib.c (working copy)
|
| @@ -57,6 +57,7 @@
|
| */
|
|
|
| #include <stdio.h>
|
| +#include <ctype.h>
|
| #include "cryptlib.h"
|
| #include <openssl/buffer.h>
|
| #include <openssl/objects.h>
|
| @@ -65,9 +66,13 @@
|
| #include <openssl/x509.h>
|
| #include <openssl/pem.h>
|
| #include <openssl/pkcs12.h>
|
| +#include "asn1_locl.h"
|
| #ifndef OPENSSL_NO_DES
|
| #include <openssl/des.h>
|
| #endif
|
| +#ifndef OPENSSL_NO_ENGINE
|
| +#include <openssl/engine.h>
|
| +#endif
|
|
|
| const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT;
|
|
|
| @@ -75,6 +80,7 @@
|
|
|
| static int load_iv(char **fromp,unsigned char *to, int num);
|
| static int check_pem(const char *nm, const char *name);
|
| +int pem_check_suffix(const char *pem_str, const char *suffix);
|
|
|
| int PEM_def_callback(char *buf, int num, int w, void *key)
|
| {
|
| @@ -99,7 +105,7 @@
|
|
|
| for (;;)
|
| {
|
| - i=EVP_read_pw_string(buf,num,prompt,w);
|
| + i=EVP_read_pw_string_min(buf,MIN_LENGTH,num,prompt,w);
|
| if (i != 0)
|
| {
|
| PEMerr(PEM_F_PEM_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD);
|
| @@ -183,20 +189,54 @@
|
|
|
| /* Make PEM_STRING_EVP_PKEY match any private key */
|
|
|
| - if(!strcmp(nm,PEM_STRING_PKCS8) &&
|
| - !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
|
| + if(!strcmp(name,PEM_STRING_EVP_PKEY))
|
| + {
|
| + int slen;
|
| + const EVP_PKEY_ASN1_METHOD *ameth;
|
| + if(!strcmp(nm,PEM_STRING_PKCS8))
|
| + return 1;
|
| + if(!strcmp(nm,PEM_STRING_PKCS8INF))
|
| + return 1;
|
| + slen = pem_check_suffix(nm, "PRIVATE KEY");
|
| + if (slen > 0)
|
| + {
|
| + /* NB: ENGINE implementations wont contain
|
| + * a deprecated old private key decode function
|
| + * so don't look for them.
|
| + */
|
| + ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
|
| + if (ameth && ameth->old_priv_decode)
|
| + return 1;
|
| + }
|
| + return 0;
|
| + }
|
|
|
| - if(!strcmp(nm,PEM_STRING_PKCS8INF) &&
|
| - !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
|
| + if(!strcmp(name,PEM_STRING_PARAMETERS))
|
| + {
|
| + int slen;
|
| + const EVP_PKEY_ASN1_METHOD *ameth;
|
| + slen = pem_check_suffix(nm, "PARAMETERS");
|
| + if (slen > 0)
|
| + {
|
| + ENGINE *e;
|
| + ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
|
| + if (ameth)
|
| + {
|
| + int r;
|
| + if (ameth->param_decode)
|
| + r = 1;
|
| + else
|
| + r = 0;
|
| +#ifndef OPENSSL_NO_ENGINE
|
| + if (e)
|
| + ENGINE_finish(e);
|
| +#endif
|
| + return r;
|
| + }
|
| + }
|
| + return 0;
|
| + }
|
|
|
| - if(!strcmp(nm,PEM_STRING_RSA) &&
|
| - !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
|
| -
|
| - if(!strcmp(nm,PEM_STRING_DSA) &&
|
| - !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
|
| -
|
| - if(!strcmp(nm,PEM_STRING_ECPRIVATEKEY) &&
|
| - !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
|
| /* Permit older strings */
|
|
|
| if(!strcmp(nm,PEM_STRING_X509_OLD) &&
|
| @@ -219,6 +259,14 @@
|
| if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
|
| !strcmp(name, PEM_STRING_PKCS7)) return 1;
|
|
|
| +#ifndef OPENSSL_NO_CMS
|
| + if(!strcmp(nm, PEM_STRING_X509) &&
|
| + !strcmp(name, PEM_STRING_CMS)) return 1;
|
| + /* Allow CMS to be read from PKCS#7 headers */
|
| + if(!strcmp(nm, PEM_STRING_PKCS7) &&
|
| + !strcmp(name, PEM_STRING_CMS)) return 1;
|
| +#endif
|
| +
|
| return 0;
|
| }
|
|
|
| @@ -264,7 +312,7 @@
|
|
|
| #ifndef OPENSSL_NO_FP_API
|
| int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
|
| - char *x, const EVP_CIPHER *enc, unsigned char *kstr,
|
| + void *x, const EVP_CIPHER *enc, unsigned char *kstr,
|
| int klen, pem_password_cb *callback, void *u)
|
| {
|
| BIO *b;
|
| @@ -283,7 +331,7 @@
|
| #endif
|
|
|
| int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
|
| - char *x, const EVP_CIPHER *enc, unsigned char *kstr,
|
| + void *x, const EVP_CIPHER *enc, unsigned char *kstr,
|
| int klen, pem_password_cb *callback, void *u)
|
| {
|
| EVP_CIPHER_CTX ctx;
|
| @@ -434,7 +482,6 @@
|
|
|
| int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
|
| {
|
| - int o;
|
| const EVP_CIPHER *enc=NULL;
|
| char *p,c;
|
| char **header_pp = &header;
|
| @@ -474,7 +521,6 @@
|
| header++;
|
| }
|
| *header='\0';
|
| - o=OBJ_sn2nid(p);
|
| cipher->cipher=enc=EVP_get_cipherbyname(p);
|
| *header=c;
|
| header++;
|
| @@ -782,3 +828,25 @@
|
| BUF_MEM_free(dataB);
|
| return(0);
|
| }
|
| +
|
| +/* Check pem string and return prefix length.
|
| + * If for example the pem_str == "RSA PRIVATE KEY" and suffix = "PRIVATE KEY"
|
| + * the return value is 3 for the string "RSA".
|
| + */
|
| +
|
| +int pem_check_suffix(const char *pem_str, const char *suffix)
|
| + {
|
| + int pem_len = strlen(pem_str);
|
| + int suffix_len = strlen(suffix);
|
| + const char *p;
|
| + if (suffix_len + 1 >= pem_len)
|
| + return 0;
|
| + p = pem_str + pem_len - suffix_len;
|
| + if (strcmp(p, suffix))
|
| + return 0;
|
| + p--;
|
| + if (*p != ' ')
|
| + return 0;
|
| + return p - pem_str;
|
| + }
|
| +
|
|
|