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.c222
1 files changed, 191 insertions, 31 deletions
diff --git a/src/lib/libcrypto/pem/pem_lib.c b/src/lib/libcrypto/pem/pem_lib.c
index 90f02011ba..072211ba0f 100644
--- a/src/lib/libcrypto/pem/pem_lib.c
+++ b/src/lib/libcrypto/pem/pem_lib.c
@@ -75,8 +75,17 @@ const char *PEM_version="PEM" OPENSSL_VERSION_PTEXT;
75 75
76static int def_callback(char *buf, int num, int w, void *userdata); 76static int def_callback(char *buf, int num, int w, void *userdata);
77static int load_iv(unsigned char **fromp,unsigned char *to, int num); 77static int load_iv(unsigned char **fromp,unsigned char *to, int num);
78 78static int check_pem(const char *nm, const char *name);
79static int def_callback(char *buf, int num, int w, void *userdata) 79static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder,
80 int nid, const EVP_CIPHER *enc,
81 char *kstr, int klen,
82 pem_password_cb *cb, void *u);
83static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder,
84 int nid, const EVP_CIPHER *enc,
85 char *kstr, int klen,
86 pem_password_cb *cb, void *u);
87
88static int def_callback(char *buf, int num, int w, void *key)
80 { 89 {
81#ifdef NO_FP_API 90#ifdef NO_FP_API
82 /* We should not ever call the default callback routine from 91 /* We should not ever call the default callback routine from
@@ -86,6 +95,12 @@ static int def_callback(char *buf, int num, int w, void *userdata)
86#else 95#else
87 int i,j; 96 int i,j;
88 const char *prompt; 97 const char *prompt;
98 if(key) {
99 i=strlen(key);
100 i=(i > num)?num:i;
101 memcpy(buf,key,i);
102 return(i);
103 }
89 104
90 prompt=EVP_get_pw_prompt(); 105 prompt=EVP_get_pw_prompt();
91 if (prompt == NULL) 106 if (prompt == NULL)
@@ -168,6 +183,47 @@ char *PEM_ASN1_read(char *(*d2i)(), const char *name, FILE *fp, char **x,
168 } 183 }
169#endif 184#endif
170 185
186static int check_pem(const char *nm, const char *name)
187{
188 /* Normal matching nm and name */
189 if (!strcmp(nm,name)) return 1;
190
191 /* Make PEM_STRING_EVP_PKEY match any private key */
192
193 if(!strcmp(nm,PEM_STRING_PKCS8) &&
194 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
195
196 if(!strcmp(nm,PEM_STRING_PKCS8INF) &&
197 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
198
199 if(!strcmp(nm,PEM_STRING_RSA) &&
200 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
201
202 if(!strcmp(nm,PEM_STRING_DSA) &&
203 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
204
205 /* Permit older strings */
206
207 if(!strcmp(nm,PEM_STRING_X509_OLD) &&
208 !strcmp(name,PEM_STRING_X509)) return 1;
209
210 if(!strcmp(nm,PEM_STRING_X509_REQ_OLD) &&
211 !strcmp(name,PEM_STRING_X509_REQ)) return 1;
212
213 /* Allow normal certs to be read as trusted certs */
214 if(!strcmp(nm,PEM_STRING_X509) &&
215 !strcmp(name,PEM_STRING_X509_TRUSTED)) return 1;
216
217 if(!strcmp(nm,PEM_STRING_X509_OLD) &&
218 !strcmp(name,PEM_STRING_X509_TRUSTED)) return 1;
219
220 /* Some CAs use PKCS#7 with CERTIFICATE headers */
221 if(!strcmp(nm, PEM_STRING_X509) &&
222 !strcmp(name, PEM_STRING_PKCS7)) return 1;
223
224 return 0;
225}
226
171char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x, 227char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x,
172 pem_password_cb *cb, void *u) 228 pem_password_cb *cb, void *u)
173 { 229 {
@@ -179,22 +235,13 @@ char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x,
179 235
180 for (;;) 236 for (;;)
181 { 237 {
182 if (!PEM_read_bio(bp,&nm,&header,&data,&len)) return(NULL); 238 if (!PEM_read_bio(bp,&nm,&header,&data,&len)) {
183 if ( (strcmp(nm,name) == 0) || 239 if(ERR_GET_REASON(ERR_peek_error()) ==
184 ((strcmp(nm,PEM_STRING_RSA) == 0) && 240 PEM_R_NO_START_LINE)
185 (strcmp(name,PEM_STRING_EVP_PKEY) == 0)) || 241 ERR_add_error_data(2, "Expecting: ", name);
186 ((strcmp(nm,PEM_STRING_DSA) == 0) && 242 return(NULL);
187 (strcmp(name,PEM_STRING_EVP_PKEY) == 0)) || 243 }
188 ((strcmp(nm,PEM_STRING_PKCS8) == 0) && 244 if(check_pem(nm, name)) break;
189 (strcmp(name,PEM_STRING_EVP_PKEY) == 0)) ||
190 ((strcmp(nm,PEM_STRING_PKCS8INF) == 0) &&
191 (strcmp(name,PEM_STRING_EVP_PKEY) == 0)) ||
192 ((strcmp(nm,PEM_STRING_X509_OLD) == 0) &&
193 (strcmp(name,PEM_STRING_X509) == 0)) ||
194 ((strcmp(nm,PEM_STRING_X509_REQ_OLD) == 0) &&
195 (strcmp(name,PEM_STRING_X509_REQ) == 0))
196 )
197 break;
198 Free(nm); 245 Free(nm);
199 Free(header); 246 Free(header);
200 Free(data); 247 Free(data);
@@ -218,7 +265,7 @@ char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x,
218 X509_SIG *p8; 265 X509_SIG *p8;
219 int klen; 266 int klen;
220 char psbuf[PEM_BUFSIZE]; 267 char psbuf[PEM_BUFSIZE];
221 p8 = d2i_X509_SIG((X509_SIG **)x, &p, len); 268 p8 = d2i_X509_SIG(NULL, &p, len);
222 if(!p8) goto p8err; 269 if(!p8) goto p8err;
223 if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u); 270 if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u);
224 else klen=def_callback(psbuf,PEM_BUFSIZE,0,u); 271 else klen=def_callback(psbuf,PEM_BUFSIZE,0,u);
@@ -231,6 +278,10 @@ char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x,
231 X509_SIG_free(p8); 278 X509_SIG_free(p8);
232 if(!p8inf) goto p8err; 279 if(!p8inf) goto p8err;
233 ret = (char *)EVP_PKCS82PKEY(p8inf); 280 ret = (char *)EVP_PKCS82PKEY(p8inf);
281 if(x) {
282 if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
283 *x = ret;
284 }
234 PKCS8_PRIV_KEY_INFO_free(p8inf); 285 PKCS8_PRIV_KEY_INFO_free(p8inf);
235 } 286 }
236 } else ret=d2i(x,&p,len); 287 } else ret=d2i(x,&p,len);
@@ -321,8 +372,9 @@ int PEM_ASN1_write_bio(int (*i2d)(), const char *name, BIO *bp, char *x,
321#endif 372#endif
322 kstr=(unsigned char *)buf; 373 kstr=(unsigned char *)buf;
323 } 374 }
324 RAND_seed(data,i);/* put in the RSA key. */ 375 RAND_add(data,i,0);/* put in the RSA key. */
325 RAND_bytes(iv,8); /* Generate a salt */ 376 if (RAND_bytes(iv,8) <= 0) /* Generate a salt */
377 goto err;
326 /* The 'iv' is used as the iv and as a salt. It is 378 /* The 'iv' is used as the iv and as a salt. It is
327 * NOT taken from the BytesToKey function */ 379 * NOT taken from the BytesToKey function */
328 EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL); 380 EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL);
@@ -743,16 +795,44 @@ err:
743 return(0); 795 return(0);
744 } 796 }
745 797
746/* This function writes a private key in PKCS#8 format: it is a "drop in" 798/* These functions write a private key in PKCS#8 format: it is a "drop in"
747 * replacement for PEM_write_bio_PrivateKey(). As usual if 'enc' is NULL then 799 * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc'
748 * it uses the unencrypted private key form. It uses PKCS#5 v2.0 password based 800 * is NULL then it uses the unencrypted private key form. The 'nid' versions
749 * encryption algorithms. 801 * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0.
750 */ 802 */
751 803
804int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
805 char *kstr, int klen,
806 pem_password_cb *cb, void *u)
807{
808 return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
809}
810
752int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, 811int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
753 char *kstr, int klen, 812 char *kstr, int klen,
754 pem_password_cb *cb, void *u) 813 pem_password_cb *cb, void *u)
755{ 814{
815 return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
816}
817
818int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
819 char *kstr, int klen,
820 pem_password_cb *cb, void *u)
821{
822 return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
823}
824
825int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
826 char *kstr, int klen,
827 pem_password_cb *cb, void *u)
828{
829 return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
830}
831
832static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
833 char *kstr, int klen,
834 pem_password_cb *cb, void *u)
835{
756 X509_SIG *p8; 836 X509_SIG *p8;
757 PKCS8_PRIV_KEY_INFO *p8inf; 837 PKCS8_PRIV_KEY_INFO *p8inf;
758 char buf[PEM_BUFSIZE]; 838 char buf[PEM_BUFSIZE];
@@ -762,7 +842,7 @@ int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
762 PEM_R_ERROR_CONVERTING_PRIVATE_KEY); 842 PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
763 return 0; 843 return 0;
764 } 844 }
765 if(enc) { 845 if(enc || (nid != -1)) {
766 if(!kstr) { 846 if(!kstr) {
767 if(!cb) klen = def_callback(buf, PEM_BUFSIZE, 1, u); 847 if(!cb) klen = def_callback(buf, PEM_BUFSIZE, 1, u);
768 else klen = cb(buf, PEM_BUFSIZE, 1, u); 848 else klen = cb(buf, PEM_BUFSIZE, 1, u);
@@ -775,29 +855,109 @@ int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
775 855
776 kstr = buf; 856 kstr = buf;
777 } 857 }
778 p8 = PKCS8_encrypt(-1, enc, kstr, klen, NULL, 0, 0, p8inf); 858 p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
779 if(kstr == buf) memset(buf, 0, klen); 859 if(kstr == buf) memset(buf, 0, klen);
780 PKCS8_PRIV_KEY_INFO_free(p8inf); 860 PKCS8_PRIV_KEY_INFO_free(p8inf);
781 ret = PEM_write_bio_PKCS8(bp, p8); 861 if(isder) ret = i2d_PKCS8_bio(bp, p8);
862 else ret = PEM_write_bio_PKCS8(bp, p8);
782 X509_SIG_free(p8); 863 X509_SIG_free(p8);
783 return ret; 864 return ret;
784 } else { 865 } else {
785 ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); 866 if(isder) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
867 else ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
786 PKCS8_PRIV_KEY_INFO_free(p8inf); 868 PKCS8_PRIV_KEY_INFO_free(p8inf);
787 return ret; 869 return ret;
788 } 870 }
789} 871}
790 872
873/* Finally the DER version to read PKCS#8 encrypted private keys. It has to be
874 * here to access the default callback.
875 */
876
877EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
878{
879 PKCS8_PRIV_KEY_INFO *p8inf = NULL;
880 X509_SIG *p8 = NULL;
881 int klen;
882 EVP_PKEY *ret;
883 char psbuf[PEM_BUFSIZE];
884 p8 = d2i_PKCS8_bio(bp, NULL);
885 if(!p8) return NULL;
886 if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u);
887 else klen=def_callback(psbuf,PEM_BUFSIZE,0,u);
888 if (klen <= 0) {
889 PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ);
890 X509_SIG_free(p8);
891 return NULL;
892 }
893 p8inf = M_PKCS8_decrypt(p8, psbuf, klen);
894 X509_SIG_free(p8);
895 if(!p8inf) return NULL;
896 ret = EVP_PKCS82PKEY(p8inf);
897 PKCS8_PRIV_KEY_INFO_free(p8inf);
898 if(!ret) return NULL;
899 if(x) {
900 if(*x) EVP_PKEY_free(*x);
901 *x = ret;
902 }
903 return ret;
904}
905
906#ifndef NO_FP_API
907
908int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
909 char *kstr, int klen,
910 pem_password_cb *cb, void *u)
911{
912 return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
913}
914
915int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
916 char *kstr, int klen,
917 pem_password_cb *cb, void *u)
918{
919 return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
920}
921
922int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
923 char *kstr, int klen,
924 pem_password_cb *cb, void *u)
925{
926 return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
927}
928
791int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, 929int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
792 char *kstr, int klen, pem_password_cb *cb, void *u) 930 char *kstr, int klen, pem_password_cb *cb, void *u)
793{ 931{
932 return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
933}
934
935static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
936 char *kstr, int klen,
937 pem_password_cb *cb, void *u)
938{
794 BIO *bp; 939 BIO *bp;
795 int ret; 940 int ret;
796 if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { 941 if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
797 PEMerr(PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY,ERR_R_BUF_LIB); 942 PEMerr(PEM_F_PEM_F_DO_PK8KEY_FP,ERR_R_BUF_LIB);
798 return(0); 943 return(0);
799 } 944 }
800 ret = PEM_write_bio_PKCS8PrivateKey(bp, x, enc, kstr, klen, cb, u); 945 ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
801 BIO_free(bp); 946 BIO_free(bp);
802 return ret; 947 return ret;
803} 948}
949
950EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
951{
952 BIO *bp;
953 EVP_PKEY *ret;
954 if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
955 PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP,ERR_R_BUF_LIB);
956 return NULL;
957 }
958 ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
959 BIO_free(bp);
960 return ret;
961}
962
963#endif