⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pem_info.c

📁 OpenSSL 0.9.8k 最新版OpenSSL
💻 C
字号:
/* crypto/pem/pem_info.c *//* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. *  * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to.  The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code.  The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). *  * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *    "This product includes cryptographic software written by *     Eric Young (eay@cryptsoft.com)" *    The word 'cryptographic' can be left out if the rouines from the library *    being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from  *    the apps directory (application code) you must include an acknowledgement: *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" *  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *  * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed.  i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */#include <stdio.h>#include "cryptlib.h"#include <openssl/buffer.h>#include <openssl/objects.h>#include <openssl/evp.h>#include <openssl/x509.h>#include <openssl/pem.h>#ifndef OPENSSL_NO_RSA#include <openssl/rsa.h>#endif#ifndef OPENSSL_NO_DSA#include <openssl/dsa.h>#endif#ifndef OPENSSL_NO_FP_APISTACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u)	{        BIO *b;        STACK_OF(X509_INFO) *ret;        if ((b=BIO_new(BIO_s_file())) == NULL)		{		PEMerr(PEM_F_PEM_X509_INFO_READ,ERR_R_BUF_LIB);                return(0);		}        BIO_set_fp(b,fp,BIO_NOCLOSE);        ret=PEM_X509_INFO_read_bio(b,sk,cb,u);        BIO_free(b);        return(ret);	}#endifSTACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u)	{	X509_INFO *xi=NULL;	char *name=NULL,*header=NULL;	void *pp;	unsigned char *data=NULL;	const unsigned char *p;	long len,error=0;	int ok=0;	STACK_OF(X509_INFO) *ret=NULL;	unsigned int i,raw;	d2i_of_void *d2i;	if (sk == NULL)		{		if ((ret=sk_X509_INFO_new_null()) == NULL)			{			PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_MALLOC_FAILURE);			goto err;			}		}	else		ret=sk;	if ((xi=X509_INFO_new()) == NULL) goto err;	for (;;)		{		raw=0;		i=PEM_read_bio(bp,&name,&header,&data,&len);		if (i == 0)			{			error=ERR_GET_REASON(ERR_peek_last_error());			if (error == PEM_R_NO_START_LINE)				{				ERR_clear_error();				break;				}			goto err;			}start:		if (	(strcmp(name,PEM_STRING_X509) == 0) ||			(strcmp(name,PEM_STRING_X509_OLD) == 0))			{			d2i=(D2I_OF(void))d2i_X509;			if (xi->x509 != NULL)				{				if (!sk_X509_INFO_push(ret,xi)) goto err;				if ((xi=X509_INFO_new()) == NULL) goto err;				goto start;				}			pp=&(xi->x509);			}		else if ((strcmp(name,PEM_STRING_X509_TRUSTED) == 0))			{			d2i=(D2I_OF(void))d2i_X509_AUX;			if (xi->x509 != NULL)				{				if (!sk_X509_INFO_push(ret,xi)) goto err;				if ((xi=X509_INFO_new()) == NULL) goto err;				goto start;				}			pp=&(xi->x509);			}		else if (strcmp(name,PEM_STRING_X509_CRL) == 0)			{			d2i=(D2I_OF(void))d2i_X509_CRL;			if (xi->crl != NULL)				{				if (!sk_X509_INFO_push(ret,xi)) goto err;				if ((xi=X509_INFO_new()) == NULL) goto err;				goto start;				}			pp=&(xi->crl);			}		else#ifndef OPENSSL_NO_RSA			if (strcmp(name,PEM_STRING_RSA) == 0)			{			d2i=(D2I_OF(void))d2i_RSAPrivateKey;			if (xi->x_pkey != NULL) 				{				if (!sk_X509_INFO_push(ret,xi)) goto err;				if ((xi=X509_INFO_new()) == NULL) goto err;				goto start;				}			xi->enc_data=NULL;			xi->enc_len=0;			xi->x_pkey=X509_PKEY_new();			if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL)				goto err;			xi->x_pkey->dec_pkey->type=EVP_PKEY_RSA;			pp=&(xi->x_pkey->dec_pkey->pkey.rsa);			if ((int)strlen(header) > 10) /* assume encrypted */				raw=1;			}		else#endif#ifndef OPENSSL_NO_DSA			if (strcmp(name,PEM_STRING_DSA) == 0)			{			d2i=(D2I_OF(void))d2i_DSAPrivateKey;			if (xi->x_pkey != NULL) 				{				if (!sk_X509_INFO_push(ret,xi)) goto err;				if ((xi=X509_INFO_new()) == NULL) goto err;				goto start;				}			xi->enc_data=NULL;			xi->enc_len=0;			xi->x_pkey=X509_PKEY_new();			if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL)				goto err;			xi->x_pkey->dec_pkey->type=EVP_PKEY_DSA;			pp=&xi->x_pkey->dec_pkey->pkey.dsa;			if ((int)strlen(header) > 10) /* assume encrypted */				raw=1;			}		else#endif#ifndef OPENSSL_NO_EC 			if (strcmp(name,PEM_STRING_ECPRIVATEKEY) == 0) 			{ 				d2i=(D2I_OF(void))d2i_ECPrivateKey; 				if (xi->x_pkey != NULL)  				{ 					if (!sk_X509_INFO_push(ret,xi)) goto err; 					if ((xi=X509_INFO_new()) == NULL) goto err; 						goto start; 				}  			xi->enc_data=NULL; 			xi->enc_len=0;  			xi->x_pkey=X509_PKEY_new(); 			if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL) 				goto err; 			xi->x_pkey->dec_pkey->type=EVP_PKEY_EC; 			pp=&(xi->x_pkey->dec_pkey->pkey.ec); 			if ((int)strlen(header) > 10) /* assume encrypted */ 				raw=1;			}		else#endif			{			d2i=NULL;			pp=NULL;			}		if (d2i != NULL)			{			if (!raw)				{				EVP_CIPHER_INFO cipher;				if (!PEM_get_EVP_CIPHER_INFO(header,&cipher))					goto err;				if (!PEM_do_header(&cipher,data,&len,cb,u))					goto err;				p=data;				if (d2i(pp,&p,len) == NULL)					{					PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB);					goto err;					}				}			else				{ /* encrypted RSA data */				if (!PEM_get_EVP_CIPHER_INFO(header,					&xi->enc_cipher)) goto err;				xi->enc_data=(char *)data;				xi->enc_len=(int)len;				data=NULL;				}			}		else	{			/* unknown */			}		if (name != NULL) OPENSSL_free(name);		if (header != NULL) OPENSSL_free(header);		if (data != NULL) OPENSSL_free(data);		name=NULL;		header=NULL;		data=NULL;		}	/* if the last one hasn't been pushed yet and there is anything	 * in it then add it to the stack ... 	 */	if ((xi->x509 != NULL) || (xi->crl != NULL) ||		(xi->x_pkey != NULL) || (xi->enc_data != NULL))		{		if (!sk_X509_INFO_push(ret,xi)) goto err;		xi=NULL;		}	ok=1;err:	if (xi != NULL) X509_INFO_free(xi);	if (!ok)		{		for (i=0; ((int)i)<sk_X509_INFO_num(ret); i++)			{			xi=sk_X509_INFO_value(ret,i);			X509_INFO_free(xi);			}		if (ret != sk) sk_X509_INFO_free(ret);		ret=NULL;		}			if (name != NULL) OPENSSL_free(name);	if (header != NULL) OPENSSL_free(header);	if (data != NULL) OPENSSL_free(data);	return(ret);	}/* A TJH addition */int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u)	{	EVP_CIPHER_CTX ctx;	int i,ret=0;	unsigned char *data=NULL;	const char *objstr=NULL;	char buf[PEM_BUFSIZE];	unsigned char *iv=NULL;		if (enc != NULL)		{		objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));		if (objstr == NULL)			{			PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);			goto err;			}		}	/* now for the fun part ... if we have a private key then 	 * we have to be able to handle a not-yet-decrypted key	 * being written out correctly ... if it is decrypted or	 * it is non-encrypted then we use the base code	 */	if (xi->x_pkey!=NULL)		{		if ( (xi->enc_data!=NULL) && (xi->enc_len>0) )			{			/* copy from weirdo names into more normal things */			iv=xi->enc_cipher.iv;			data=(unsigned char *)xi->enc_data;			i=xi->enc_len;			/* we take the encryption data from the			 * internal stuff rather than what the			 * user has passed us ... as we have to 			 * match exactly for some strange reason			 */			objstr=OBJ_nid2sn(				EVP_CIPHER_nid(xi->enc_cipher.cipher));			if (objstr == NULL)				{				PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);				goto err;				}			/* create the right magic header stuff */			OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf);			buf[0]='\0';			PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);			PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv);			/* use the normal code to write things out */			i=PEM_write_bio(bp,PEM_STRING_RSA,buf,data,i);			if (i <= 0) goto err;			}		else			{			/* Add DSA/DH */#ifndef OPENSSL_NO_RSA			/* normal optionally encrypted stuff */			if (PEM_write_bio_RSAPrivateKey(bp,				xi->x_pkey->dec_pkey->pkey.rsa,				enc,kstr,klen,cb,u)<=0)				goto err;#endif			}		}	/* if we have a certificate then write it out now */	if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp,xi->x509) <= 0))		goto err;	/* we are ignoring anything else that is loaded into the X509_INFO	 * structure for the moment ... as I don't need it so I'm not	 * coding it here and Eric can do it when this makes it into the	 * base library --tjh	 */	ret=1;err:	OPENSSL_cleanse((char *)&ctx,sizeof(ctx));	OPENSSL_cleanse(buf,PEM_BUFSIZE);	return(ret);	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -