From b7326b0b437bf521b76709b570a3d552fa59d846 Mon Sep 17 00:00:00 2001 From: Matt Braithwaite Date: Tue, 2 Jun 2015 12:42:02 -0700 Subject: [PATCH] Implement |PEM_def_callback| and call it where appropriate. This implementation does not prompt for a password. It's just enough to ensure that the many functions that take a tuple of |pem_password_cb| and a |void *| to a password work in a reasonable way when the latter is non-NULL. Change-Id: Ic6bfc484630c67b5ede25277e14eb3b00c2024f0 Reviewed-on: https://boringssl-review.googlesource.com/4990 Reviewed-by: Adam Langley --- crypto/pem/pem_lib.c | 23 +++++++++++++++++++---- crypto/pem/pem_pk8.c | 8 ++++---- crypto/pem/pem_pkey.c | 4 ++-- include/openssl/pem.h | 12 ++++++------ 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c index 48e3297c..52014671 100644 --- a/crypto/pem/pem_lib.c +++ b/crypto/pem/pem_lib.c @@ -331,8 +331,9 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, if (kstr == NULL) { klen = 0; - if (callback) - klen=(*callback)(buf,PEM_BUFSIZE,1,u); + if (!callback) + callback = PEM_def_callback; + klen=(*callback)(buf,PEM_BUFSIZE,1,u); if (klen <= 0) { OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write_bio, PEM_R_READ_KEY); @@ -403,8 +404,8 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, if (cipher->cipher == NULL) return(1); klen = 0; - if (callback) - klen=callback(buf,PEM_BUFSIZE,0,u); + if (!callback) callback = PEM_def_callback; + klen=callback(buf,PEM_BUFSIZE,0,u); if (klen <= 0) { OPENSSL_PUT_ERROR(PEM, PEM_do_header, PEM_R_BAD_PASSWORD_READ); @@ -811,3 +812,17 @@ int pem_check_suffix(const char *pem_str, const char *suffix) return p - pem_str; } +int PEM_def_callback(char *buf, int size, int rwflag, void *userdata) + { + if (!buf || !userdata) + { + return 0; + } + size_t len = strlen((char *) userdata); + if (len >= (size_t) size) + { + return 0; + } + strcpy(buf, (char *) userdata); + return len; + } diff --git a/crypto/pem/pem_pk8.c b/crypto/pem/pem_pk8.c index 383a5240..035038e0 100644 --- a/crypto/pem/pem_pk8.c +++ b/crypto/pem/pem_pk8.c @@ -124,8 +124,8 @@ static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER if(enc || (nid != -1)) { if(!kstr) { klen = 0; - if (cb) - klen = cb(buf, PEM_BUFSIZE, 1, u); + if (!cb) cb = PEM_def_callback; + klen = cb(buf, PEM_BUFSIZE, 1, u); if(klen <= 0) { OPENSSL_PUT_ERROR(PEM, do_pk8pkey, PEM_R_READ_KEY); PKCS8_PRIV_KEY_INFO_free(p8inf); @@ -160,8 +160,8 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo if(!p8) return NULL; klen = 0; - if (cb) - klen=cb(psbuf,PEM_BUFSIZE,0,u); + if (!cb) cb = PEM_def_callback; + klen=cb(psbuf,PEM_BUFSIZE,0,u); if (klen <= 0) { OPENSSL_PUT_ERROR(PEM, d2i_PKCS8PrivateKey_bio, PEM_R_BAD_PASSWORD_READ); X509_SIG_free(p8); diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c index c0aba51f..fe58558a 100644 --- a/crypto/pem/pem_pkey.c +++ b/crypto/pem/pem_pkey.c @@ -106,7 +106,8 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo if(!p8) goto p8err; klen = 0; - if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u); + if (!cb) cb = PEM_def_callback; + klen=cb(psbuf,PEM_BUFSIZE,0,u); if (klen <= 0) { OPENSSL_PUT_ERROR(PEM, PEM_read_bio_PrivateKey, PEM_R_BAD_PASSWORD_READ); X509_SIG_free(p8); @@ -309,4 +310,3 @@ DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u) return(ret); } #endif - diff --git a/include/openssl/pem.h b/include/openssl/pem.h index adc8d862..7756e45e 100644 --- a/include/openssl/pem.h +++ b/include/openssl/pem.h @@ -381,13 +381,8 @@ OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, DECLARE_PEM_read(name, type) \ DECLARE_PEM_write_cb(name, type) -#if 1 /* "userdata": new with OpenSSL 0.9.4 */ typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata); -#else -/* OpenSSL 0.9.3, 0.9.3a */ -typedef int pem_password_cb(char *buf, int size, int rwflag); -#endif OPENSSL_EXPORT int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); OPENSSL_EXPORT int PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data,long *len, pem_password_cb *callback,void *u); @@ -415,7 +410,12 @@ OPENSSL_EXPORT void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type); OPENSSL_EXPORT void PEM_SignUpdate(EVP_MD_CTX *ctx,unsigned char *d,unsigned int cnt); OPENSSL_EXPORT int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, EVP_PKEY *pkey); -OPENSSL_EXPORT int PEM_def_callback(char *buf, int num, int w, void *key); +/* |PEM_def_callback| treats |userdata| as a string and copies it into |buf|, + * assuming its |size| is sufficient. Returns the length of the string, or 0 + * if there is not enough room. If either |buf| or |userdata| is NULL, 0 is + * returned. Note that this is different from OpenSSL, which prompts for a + * password. */ +OPENSSL_EXPORT int PEM_def_callback(char *buf, int size, int rwflag, void *userdata); OPENSSL_EXPORT void PEM_proc_type(char *buf, int type); OPENSSL_EXPORT void PEM_dek_info(char *buf, const char *type, int len, char *str);