1*0Sstevel@tonic-gate /* crypto/pem/pem_info.c */ 2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*0Sstevel@tonic-gate * All rights reserved. 4*0Sstevel@tonic-gate * 5*0Sstevel@tonic-gate * This package is an SSL implementation written 6*0Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com). 7*0Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as 10*0Sstevel@tonic-gate * the following conditions are aheared to. The following conditions 11*0Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA, 12*0Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*0Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms 14*0Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*0Sstevel@tonic-gate * 16*0Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in 17*0Sstevel@tonic-gate * the code are not to be removed. 18*0Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution 19*0Sstevel@tonic-gate * as the author of the parts of the library used. 20*0Sstevel@tonic-gate * This can be in the form of a textual message at program startup or 21*0Sstevel@tonic-gate * in documentation (online or textual) provided with the package. 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 24*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 25*0Sstevel@tonic-gate * are met: 26*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright 27*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 28*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 29*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 30*0Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 31*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 32*0Sstevel@tonic-gate * must display the following acknowledgement: 33*0Sstevel@tonic-gate * "This product includes cryptographic software written by 34*0Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)" 35*0Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library 36*0Sstevel@tonic-gate * being used are not cryptographic related :-). 37*0Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from 38*0Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement: 39*0Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*0Sstevel@tonic-gate * 41*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*0Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*0Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*0Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*0Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*0Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*0Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*0Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*0Sstevel@tonic-gate * SUCH DAMAGE. 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * The licence and distribution terms for any publically available version or 54*0Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be 55*0Sstevel@tonic-gate * copied and put under another distribution licence 56*0Sstevel@tonic-gate * [including the GNU Public Licence.] 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate #include <stdio.h> 60*0Sstevel@tonic-gate #include "cryptlib.h" 61*0Sstevel@tonic-gate #include <openssl/buffer.h> 62*0Sstevel@tonic-gate #include <openssl/objects.h> 63*0Sstevel@tonic-gate #include <openssl/evp.h> 64*0Sstevel@tonic-gate #include <openssl/x509.h> 65*0Sstevel@tonic-gate #include <openssl/pem.h> 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate #ifndef OPENSSL_NO_FP_API 68*0Sstevel@tonic-gate STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u) 69*0Sstevel@tonic-gate { 70*0Sstevel@tonic-gate BIO *b; 71*0Sstevel@tonic-gate STACK_OF(X509_INFO) *ret; 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate if ((b=BIO_new(BIO_s_file())) == NULL) 74*0Sstevel@tonic-gate { 75*0Sstevel@tonic-gate PEMerr(PEM_F_PEM_X509_INFO_READ,ERR_R_BUF_LIB); 76*0Sstevel@tonic-gate return(0); 77*0Sstevel@tonic-gate } 78*0Sstevel@tonic-gate BIO_set_fp(b,fp,BIO_NOCLOSE); 79*0Sstevel@tonic-gate ret=PEM_X509_INFO_read_bio(b,sk,cb,u); 80*0Sstevel@tonic-gate BIO_free(b); 81*0Sstevel@tonic-gate return(ret); 82*0Sstevel@tonic-gate } 83*0Sstevel@tonic-gate #endif 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u) 86*0Sstevel@tonic-gate { 87*0Sstevel@tonic-gate X509_INFO *xi=NULL; 88*0Sstevel@tonic-gate char *name=NULL,*header=NULL,**pp; 89*0Sstevel@tonic-gate unsigned char *data=NULL,*p; 90*0Sstevel@tonic-gate long len,error=0; 91*0Sstevel@tonic-gate int ok=0; 92*0Sstevel@tonic-gate STACK_OF(X509_INFO) *ret=NULL; 93*0Sstevel@tonic-gate unsigned int i,raw; 94*0Sstevel@tonic-gate char *(*d2i)(); 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate if (sk == NULL) 97*0Sstevel@tonic-gate { 98*0Sstevel@tonic-gate if ((ret=sk_X509_INFO_new_null()) == NULL) 99*0Sstevel@tonic-gate { 100*0Sstevel@tonic-gate PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_MALLOC_FAILURE); 101*0Sstevel@tonic-gate goto err; 102*0Sstevel@tonic-gate } 103*0Sstevel@tonic-gate } 104*0Sstevel@tonic-gate else 105*0Sstevel@tonic-gate ret=sk; 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate if ((xi=X509_INFO_new()) == NULL) goto err; 108*0Sstevel@tonic-gate for (;;) 109*0Sstevel@tonic-gate { 110*0Sstevel@tonic-gate raw=0; 111*0Sstevel@tonic-gate i=PEM_read_bio(bp,&name,&header,&data,&len); 112*0Sstevel@tonic-gate if (i == 0) 113*0Sstevel@tonic-gate { 114*0Sstevel@tonic-gate error=ERR_GET_REASON(ERR_peek_last_error()); 115*0Sstevel@tonic-gate if (error == PEM_R_NO_START_LINE) 116*0Sstevel@tonic-gate { 117*0Sstevel@tonic-gate ERR_clear_error(); 118*0Sstevel@tonic-gate break; 119*0Sstevel@tonic-gate } 120*0Sstevel@tonic-gate goto err; 121*0Sstevel@tonic-gate } 122*0Sstevel@tonic-gate start: 123*0Sstevel@tonic-gate if ( (strcmp(name,PEM_STRING_X509) == 0) || 124*0Sstevel@tonic-gate (strcmp(name,PEM_STRING_X509_OLD) == 0)) 125*0Sstevel@tonic-gate { 126*0Sstevel@tonic-gate d2i=(char *(*)())d2i_X509; 127*0Sstevel@tonic-gate if (xi->x509 != NULL) 128*0Sstevel@tonic-gate { 129*0Sstevel@tonic-gate if (!sk_X509_INFO_push(ret,xi)) goto err; 130*0Sstevel@tonic-gate if ((xi=X509_INFO_new()) == NULL) goto err; 131*0Sstevel@tonic-gate goto start; 132*0Sstevel@tonic-gate } 133*0Sstevel@tonic-gate pp=(char **)&(xi->x509); 134*0Sstevel@tonic-gate } 135*0Sstevel@tonic-gate else if ((strcmp(name,PEM_STRING_X509_TRUSTED) == 0)) 136*0Sstevel@tonic-gate { 137*0Sstevel@tonic-gate d2i=(char *(*)())d2i_X509_AUX; 138*0Sstevel@tonic-gate if (xi->x509 != NULL) 139*0Sstevel@tonic-gate { 140*0Sstevel@tonic-gate if (!sk_X509_INFO_push(ret,xi)) goto err; 141*0Sstevel@tonic-gate if ((xi=X509_INFO_new()) == NULL) goto err; 142*0Sstevel@tonic-gate goto start; 143*0Sstevel@tonic-gate } 144*0Sstevel@tonic-gate pp=(char **)&(xi->x509); 145*0Sstevel@tonic-gate } 146*0Sstevel@tonic-gate else if (strcmp(name,PEM_STRING_X509_CRL) == 0) 147*0Sstevel@tonic-gate { 148*0Sstevel@tonic-gate d2i=(char *(*)())d2i_X509_CRL; 149*0Sstevel@tonic-gate if (xi->crl != NULL) 150*0Sstevel@tonic-gate { 151*0Sstevel@tonic-gate if (!sk_X509_INFO_push(ret,xi)) goto err; 152*0Sstevel@tonic-gate if ((xi=X509_INFO_new()) == NULL) goto err; 153*0Sstevel@tonic-gate goto start; 154*0Sstevel@tonic-gate } 155*0Sstevel@tonic-gate pp=(char **)&(xi->crl); 156*0Sstevel@tonic-gate } 157*0Sstevel@tonic-gate else 158*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 159*0Sstevel@tonic-gate if (strcmp(name,PEM_STRING_RSA) == 0) 160*0Sstevel@tonic-gate { 161*0Sstevel@tonic-gate d2i=(char *(*)())d2i_RSAPrivateKey; 162*0Sstevel@tonic-gate if (xi->x_pkey != NULL) 163*0Sstevel@tonic-gate { 164*0Sstevel@tonic-gate if (!sk_X509_INFO_push(ret,xi)) goto err; 165*0Sstevel@tonic-gate if ((xi=X509_INFO_new()) == NULL) goto err; 166*0Sstevel@tonic-gate goto start; 167*0Sstevel@tonic-gate } 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate xi->enc_data=NULL; 170*0Sstevel@tonic-gate xi->enc_len=0; 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate xi->x_pkey=X509_PKEY_new(); 173*0Sstevel@tonic-gate if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL) 174*0Sstevel@tonic-gate goto err; 175*0Sstevel@tonic-gate xi->x_pkey->dec_pkey->type=EVP_PKEY_RSA; 176*0Sstevel@tonic-gate pp=(char **)&(xi->x_pkey->dec_pkey->pkey.rsa); 177*0Sstevel@tonic-gate if ((int)strlen(header) > 10) /* assume encrypted */ 178*0Sstevel@tonic-gate raw=1; 179*0Sstevel@tonic-gate } 180*0Sstevel@tonic-gate else 181*0Sstevel@tonic-gate #endif 182*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 183*0Sstevel@tonic-gate if (strcmp(name,PEM_STRING_DSA) == 0) 184*0Sstevel@tonic-gate { 185*0Sstevel@tonic-gate d2i=(char *(*)())d2i_DSAPrivateKey; 186*0Sstevel@tonic-gate if (xi->x_pkey != NULL) 187*0Sstevel@tonic-gate { 188*0Sstevel@tonic-gate if (!sk_X509_INFO_push(ret,xi)) goto err; 189*0Sstevel@tonic-gate if ((xi=X509_INFO_new()) == NULL) goto err; 190*0Sstevel@tonic-gate goto start; 191*0Sstevel@tonic-gate } 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate xi->enc_data=NULL; 194*0Sstevel@tonic-gate xi->enc_len=0; 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gate xi->x_pkey=X509_PKEY_new(); 197*0Sstevel@tonic-gate if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL) 198*0Sstevel@tonic-gate goto err; 199*0Sstevel@tonic-gate xi->x_pkey->dec_pkey->type=EVP_PKEY_DSA; 200*0Sstevel@tonic-gate pp=(char **)&(xi->x_pkey->dec_pkey->pkey.dsa); 201*0Sstevel@tonic-gate if ((int)strlen(header) > 10) /* assume encrypted */ 202*0Sstevel@tonic-gate raw=1; 203*0Sstevel@tonic-gate } 204*0Sstevel@tonic-gate else 205*0Sstevel@tonic-gate #endif 206*0Sstevel@tonic-gate { 207*0Sstevel@tonic-gate d2i=NULL; 208*0Sstevel@tonic-gate pp=NULL; 209*0Sstevel@tonic-gate } 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate if (d2i != NULL) 212*0Sstevel@tonic-gate { 213*0Sstevel@tonic-gate if (!raw) 214*0Sstevel@tonic-gate { 215*0Sstevel@tonic-gate EVP_CIPHER_INFO cipher; 216*0Sstevel@tonic-gate 217*0Sstevel@tonic-gate if (!PEM_get_EVP_CIPHER_INFO(header,&cipher)) 218*0Sstevel@tonic-gate goto err; 219*0Sstevel@tonic-gate if (!PEM_do_header(&cipher,data,&len,cb,u)) 220*0Sstevel@tonic-gate goto err; 221*0Sstevel@tonic-gate p=data; 222*0Sstevel@tonic-gate if (d2i(pp,&p,len) == NULL) 223*0Sstevel@tonic-gate { 224*0Sstevel@tonic-gate PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB); 225*0Sstevel@tonic-gate goto err; 226*0Sstevel@tonic-gate } 227*0Sstevel@tonic-gate } 228*0Sstevel@tonic-gate else 229*0Sstevel@tonic-gate { /* encrypted RSA data */ 230*0Sstevel@tonic-gate if (!PEM_get_EVP_CIPHER_INFO(header, 231*0Sstevel@tonic-gate &xi->enc_cipher)) goto err; 232*0Sstevel@tonic-gate xi->enc_data=(char *)data; 233*0Sstevel@tonic-gate xi->enc_len=(int)len; 234*0Sstevel@tonic-gate data=NULL; 235*0Sstevel@tonic-gate } 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate else { 238*0Sstevel@tonic-gate /* unknown */ 239*0Sstevel@tonic-gate } 240*0Sstevel@tonic-gate if (name != NULL) OPENSSL_free(name); 241*0Sstevel@tonic-gate if (header != NULL) OPENSSL_free(header); 242*0Sstevel@tonic-gate if (data != NULL) OPENSSL_free(data); 243*0Sstevel@tonic-gate name=NULL; 244*0Sstevel@tonic-gate header=NULL; 245*0Sstevel@tonic-gate data=NULL; 246*0Sstevel@tonic-gate } 247*0Sstevel@tonic-gate 248*0Sstevel@tonic-gate /* if the last one hasn't been pushed yet and there is anything 249*0Sstevel@tonic-gate * in it then add it to the stack ... 250*0Sstevel@tonic-gate */ 251*0Sstevel@tonic-gate if ((xi->x509 != NULL) || (xi->crl != NULL) || 252*0Sstevel@tonic-gate (xi->x_pkey != NULL) || (xi->enc_data != NULL)) 253*0Sstevel@tonic-gate { 254*0Sstevel@tonic-gate if (!sk_X509_INFO_push(ret,xi)) goto err; 255*0Sstevel@tonic-gate xi=NULL; 256*0Sstevel@tonic-gate } 257*0Sstevel@tonic-gate ok=1; 258*0Sstevel@tonic-gate err: 259*0Sstevel@tonic-gate if (xi != NULL) X509_INFO_free(xi); 260*0Sstevel@tonic-gate if (!ok) 261*0Sstevel@tonic-gate { 262*0Sstevel@tonic-gate for (i=0; ((int)i)<sk_X509_INFO_num(ret); i++) 263*0Sstevel@tonic-gate { 264*0Sstevel@tonic-gate xi=sk_X509_INFO_value(ret,i); 265*0Sstevel@tonic-gate X509_INFO_free(xi); 266*0Sstevel@tonic-gate } 267*0Sstevel@tonic-gate if (ret != sk) sk_X509_INFO_free(ret); 268*0Sstevel@tonic-gate ret=NULL; 269*0Sstevel@tonic-gate } 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate if (name != NULL) OPENSSL_free(name); 272*0Sstevel@tonic-gate if (header != NULL) OPENSSL_free(header); 273*0Sstevel@tonic-gate if (data != NULL) OPENSSL_free(data); 274*0Sstevel@tonic-gate return(ret); 275*0Sstevel@tonic-gate } 276*0Sstevel@tonic-gate 277*0Sstevel@tonic-gate 278*0Sstevel@tonic-gate /* A TJH addition */ 279*0Sstevel@tonic-gate int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, 280*0Sstevel@tonic-gate unsigned char *kstr, int klen, pem_password_cb *cb, void *u) 281*0Sstevel@tonic-gate { 282*0Sstevel@tonic-gate EVP_CIPHER_CTX ctx; 283*0Sstevel@tonic-gate int i,ret=0; 284*0Sstevel@tonic-gate unsigned char *data=NULL; 285*0Sstevel@tonic-gate const char *objstr=NULL; 286*0Sstevel@tonic-gate char buf[PEM_BUFSIZE]; 287*0Sstevel@tonic-gate unsigned char *iv=NULL; 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate if (enc != NULL) 290*0Sstevel@tonic-gate { 291*0Sstevel@tonic-gate objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc)); 292*0Sstevel@tonic-gate if (objstr == NULL) 293*0Sstevel@tonic-gate { 294*0Sstevel@tonic-gate PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER); 295*0Sstevel@tonic-gate goto err; 296*0Sstevel@tonic-gate } 297*0Sstevel@tonic-gate } 298*0Sstevel@tonic-gate 299*0Sstevel@tonic-gate /* now for the fun part ... if we have a private key then 300*0Sstevel@tonic-gate * we have to be able to handle a not-yet-decrypted key 301*0Sstevel@tonic-gate * being written out correctly ... if it is decrypted or 302*0Sstevel@tonic-gate * it is non-encrypted then we use the base code 303*0Sstevel@tonic-gate */ 304*0Sstevel@tonic-gate if (xi->x_pkey!=NULL) 305*0Sstevel@tonic-gate { 306*0Sstevel@tonic-gate if ( (xi->enc_data!=NULL) && (xi->enc_len>0) ) 307*0Sstevel@tonic-gate { 308*0Sstevel@tonic-gate /* copy from weirdo names into more normal things */ 309*0Sstevel@tonic-gate iv=xi->enc_cipher.iv; 310*0Sstevel@tonic-gate data=(unsigned char *)xi->enc_data; 311*0Sstevel@tonic-gate i=xi->enc_len; 312*0Sstevel@tonic-gate 313*0Sstevel@tonic-gate /* we take the encryption data from the 314*0Sstevel@tonic-gate * internal stuff rather than what the 315*0Sstevel@tonic-gate * user has passed us ... as we have to 316*0Sstevel@tonic-gate * match exactly for some strange reason 317*0Sstevel@tonic-gate */ 318*0Sstevel@tonic-gate objstr=OBJ_nid2sn( 319*0Sstevel@tonic-gate EVP_CIPHER_nid(xi->enc_cipher.cipher)); 320*0Sstevel@tonic-gate if (objstr == NULL) 321*0Sstevel@tonic-gate { 322*0Sstevel@tonic-gate PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER); 323*0Sstevel@tonic-gate goto err; 324*0Sstevel@tonic-gate } 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate /* create the right magic header stuff */ 327*0Sstevel@tonic-gate OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf); 328*0Sstevel@tonic-gate buf[0]='\0'; 329*0Sstevel@tonic-gate PEM_proc_type(buf,PEM_TYPE_ENCRYPTED); 330*0Sstevel@tonic-gate PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv); 331*0Sstevel@tonic-gate 332*0Sstevel@tonic-gate /* use the normal code to write things out */ 333*0Sstevel@tonic-gate i=PEM_write_bio(bp,PEM_STRING_RSA,buf,data,i); 334*0Sstevel@tonic-gate if (i <= 0) goto err; 335*0Sstevel@tonic-gate } 336*0Sstevel@tonic-gate else 337*0Sstevel@tonic-gate { 338*0Sstevel@tonic-gate /* Add DSA/DH */ 339*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 340*0Sstevel@tonic-gate /* normal optionally encrypted stuff */ 341*0Sstevel@tonic-gate if (PEM_write_bio_RSAPrivateKey(bp, 342*0Sstevel@tonic-gate xi->x_pkey->dec_pkey->pkey.rsa, 343*0Sstevel@tonic-gate enc,kstr,klen,cb,u)<=0) 344*0Sstevel@tonic-gate goto err; 345*0Sstevel@tonic-gate #endif 346*0Sstevel@tonic-gate } 347*0Sstevel@tonic-gate } 348*0Sstevel@tonic-gate 349*0Sstevel@tonic-gate /* if we have a certificate then write it out now */ 350*0Sstevel@tonic-gate if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp,xi->x509) <= 0)) 351*0Sstevel@tonic-gate goto err; 352*0Sstevel@tonic-gate 353*0Sstevel@tonic-gate /* we are ignoring anything else that is loaded into the X509_INFO 354*0Sstevel@tonic-gate * structure for the moment ... as I don't need it so I'm not 355*0Sstevel@tonic-gate * coding it here and Eric can do it when this makes it into the 356*0Sstevel@tonic-gate * base library --tjh 357*0Sstevel@tonic-gate */ 358*0Sstevel@tonic-gate 359*0Sstevel@tonic-gate ret=1; 360*0Sstevel@tonic-gate 361*0Sstevel@tonic-gate err: 362*0Sstevel@tonic-gate OPENSSL_cleanse((char *)&ctx,sizeof(ctx)); 363*0Sstevel@tonic-gate OPENSSL_cleanse(buf,PEM_BUFSIZE); 364*0Sstevel@tonic-gate return(ret); 365*0Sstevel@tonic-gate } 366