添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
2 * All rights reserved. 4 * This package is an SSL implementation written 5 * by Eric Young ( [email protected] ). 6 * The implementation was written so as to conform with Netscapes SSL. 8 * This library is free for commercial and non-commercial use as long as 9 * the following conditions are aheared to. The following conditions 10 * apply to all code found in this distribution, be it the RC4, RSA, 11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * included with this distribution is covered by the same copyright terms 13 * except that the holder is Tim Hudson ( [email protected] ). 16 * the code are not to be removed. 17 * If this package is used in a product, Eric Young should be given attribution 18 * as the author of the parts of the library used. 19 * This can be in the form of a textual message at program startup or 20 * in documentation (online or textual) provided with the package. 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * "This product includes cryptographic software written by 33 * Eric Young ( [email protected] )" 34 * The word 'cryptographic' can be left out if the rouines from the library 35 * being used are not cryptographic related :-). 36 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * the apps directory (application code) you must include an acknowledgement: 38 * "This product includes software written by Tim Hudson ( [email protected] )" 40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 52 * The licence and distribution terms for any publically available version or 53 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * copied and put under another distribution licence 55 * [including the GNU Public Licence.] */ 57 #include <openssl/pem.h> 59 #include <stdio.h> 60 #include <string.h> 62 #include <openssl/dh.h> 63 #include <openssl/err.h> 64 #include <openssl/evp.h> 65 #include <openssl/mem.h> 66 #include <openssl/obj.h> 67 #include <openssl/pkcs8.h> 68 #include <openssl/rand.h> 69 #include <openssl/x509.h> 71 EVP_PKEY * PEM_read_bio_PrivateKey ( BIO * bp , EVP_PKEY ** x , pem_password_cb * cb , 72 void * u ) 74 char * nm = NULL ; 75 const unsigned char * p = NULL ; 76 unsigned char * data = NULL ; 77 long len ; 78 EVP_PKEY * ret = NULL ; 80 if (! PEM_bytes_read_bio (& data , & len , & nm , PEM_STRING_EVP_PKEY , bp , cb , u )) 81 return NULL ; 82 p = data ; 84 if ( strcmp ( nm , PEM_STRING_PKCS8INF ) == 0 ) { 85 PKCS8_PRIV_KEY_INFO * p8inf ; 86 p8inf = d2i_PKCS8_PRIV_KEY_INFO ( NULL , & p , len ); 87 if (! p8inf ) 88 goto p8err ; 89 ret = EVP_PKCS82PKEY ( p8inf ); 90 if ( x ) { 91 if (* x ) 92 EVP_PKEY_free (( EVP_PKEY *)* x ); 93 * x = ret ; 95 PKCS8_PRIV_KEY_INFO_free ( p8inf ); 96 } else if ( strcmp ( nm , PEM_STRING_PKCS8 ) == 0 ) { 97 PKCS8_PRIV_KEY_INFO * p8inf ; 98 X509_SIG * p8 ; 99 int klen ; 100 char psbuf [ PEM_BUFSIZE ]; 101 p8 = d2i_X509_SIG ( NULL , & p , len ); 102 if (! p8 ) 103 goto p8err ; 105 klen = 0 ; 106 if (! cb ) 107 cb = PEM_def_callback ; 108 klen = cb ( psbuf , PEM_BUFSIZE , 0 , u ); 109 if ( klen <= 0 ) { 110 OPENSSL_PUT_ERROR (PEM, PEM_R_BAD_PASSWORD_READ ); 111 X509_SIG_free ( p8 ); 112 goto err ; 113 } 114 p8inf = PKCS8_decrypt ( p8 , psbuf , klen ); 115 X509_SIG_free ( p8 ); 116 OPENSSL_cleanse ( psbuf , klen ); 117 if (! p8inf ) 118 goto p8err ; 119 ret = EVP_PKCS82PKEY ( p8inf ); 120 if ( x ) { 121 if (* x ) 122 EVP_PKEY_free (( EVP_PKEY *)* x ); 123 * x = ret ; 124 } 125 PKCS8_PRIV_KEY_INFO_free ( p8inf ); 126 } else if ( strcmp ( nm , PEM_STRING_RSA ) == 0 ) { 127 /* TODO(davidben): d2i_PrivateKey parses PKCS#8 along with the 128 * standalone format. This and the cases below probably should not 129 * accept PKCS#8. */ 130 ret = d2i_PrivateKey ( EVP_PKEY_RSA , x , & p , len ); 131 } else if ( strcmp ( nm , PEM_STRING_EC ) == 0 ) { 132 ret = d2i_PrivateKey ( EVP_PKEY_EC , x , & p , len ); 133 } else if ( strcmp ( nm , PEM_STRING_DSA ) == 0 ) { 134 ret = d2i_PrivateKey ( EVP_PKEY_DSA , x , & p , len ); 135 } 136 p8err : 137 if ( ret == NULL ) 138 OPENSSL_PUT_ERROR (PEM, ERR_R_ASN1_LIB ); 140 err : 141 OPENSSL_free ( nm ); 142 OPENSSL_free ( data ); 143 return ( ret ); 144} 146 int PEM_write_bio_PrivateKey ( BIO * bp , EVP_PKEY * x , const EVP_CIPHER * enc , 147 unsigned char * kstr , int klen , 148 pem_password_cb * cb , void * u ) 149{ 150 return PEM_write_bio_PKCS8PrivateKey ( bp , x , enc , ( char *) kstr , klen , cb , u ); 151} 153 EVP_PKEY * PEM_read_PrivateKey ( FILE * fp , EVP_PKEY ** x , pem_password_cb * cb , 154 void * u ) 155{ 156 BIO * b = BIO_new_fp ( fp , BIO_NOCLOSE ); 157 if ( b == NULL ) { 158 OPENSSL_PUT_ERROR (PEM, ERR_R_BUF_LIB ); 159 return NULL ; 160 } 161 EVP_PKEY * ret = PEM_read_bio_PrivateKey ( b , x , cb , u ); 162 BIO_free ( b ); 163 return ret ; 164} 166 int PEM_write_PrivateKey ( FILE * fp , EVP_PKEY * x , const EVP_CIPHER * enc , 167 unsigned char * kstr , int klen , 168 pem_password_cb * cb , void * u ) 169{ 170 BIO * b = BIO_new_fp ( fp , BIO_NOCLOSE ); 171 if ( b == NULL ) { 172 OPENSSL_PUT_ERROR (PEM, ERR_R_BUF_LIB ); 173 return 0 ; 174 } 175 int ret = PEM_write_bio_PrivateKey ( b , x , enc , kstr , klen , cb , u ); 176 BIO_free ( b ); 177 return ret ; 178} 181 /* Transparently read in PKCS#3 or X9.42 DH parameters */ 183 DH * PEM_read_bio_DHparams ( BIO * bp , DH ** x , pem_password_cb * cb , void * u ) 184{ 185 char * nm = NULL ; 186 const unsigned char * p = NULL ; 187 unsigned char * data = NULL ; 188 long len ; 189 DH * ret = NULL ; 191 if (! PEM_bytes_read_bio (& data , & len , & nm , PEM_STRING_DHPARAMS , bp , cb , u )) 192 return NULL ; 193 p = data ; 195 ret = d2i_DHparams ( x , & p , len ); 197 if ( ret == NULL ) 198 OPENSSL_PUT_ERROR (PEM, ERR_R_ASN1_LIB ); 199 OPENSSL_free ( nm ); 200 OPENSSL_free ( data ); 201 return ret ; 202} 204 DH * PEM_read_DHparams ( FILE * fp , DH ** x , pem_password_cb * cb , void * u ) 205{ 206 BIO * b = BIO_new_fp ( fp , BIO_NOCLOSE ); 207 if ( b == NULL ) { 208 OPENSSL_PUT_ERROR (PEM, ERR_R_BUF_LIB ); 209 return NULL ; 210 } 211 DH * ret = PEM_read_bio_DHparams ( b , x , cb , u ); 212 BIO_free ( b ); 213 return ret ;