X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=ssl%2Fssl_rsa.c;h=03828b66326262034b515d057469bcbcdfb198da;hb=042e57d5628244b121836881c433b6fa2b6f1697;hp=3a7b8d3c361cf07b51691e04e69f999adc446b1e;hpb=eda1f21f1af8b6f77327e7b37573af9c1ba73726;p=openssl.git diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c index 3a7b8d3c36..03828b6632 100644 --- a/ssl/ssl_rsa.c +++ b/ssl/ssl_rsa.c @@ -1,5 +1,5 @@ /* ssl/ssl_rsa.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -57,63 +57,39 @@ */ #include -#include "bio.h" -#include "objects.h" -#include "evp.h" -#include "x509.h" -#include "pem.h" #include "ssl_locl.h" +#include +#include +#include +#include +#include -#ifndef NOPROTO static int ssl_set_cert(CERT *c, X509 *x509); static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); -#else -static int ssl_set_cert(); -static int ssl_set_pkey(); -#endif - -int SSL_use_certificate(ssl, x) -SSL *ssl; -X509 *x; +int SSL_use_certificate(SSL *ssl, X509 *x) { - CERT *c; - if (x == NULL) { SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER); return(0); } - if ((ssl->cert == NULL) || (ssl->cert == ssl->ctx->default_cert)) + if (!ssl_cert_inst(&ssl->cert)) { - c=ssl_cert_new(); - if (c == NULL) - { - SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE); - return(0); - } - if (ssl->cert != NULL) ssl_cert_free(ssl->cert); - ssl->cert=c; + SSLerr(SSL_F_SSL_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE); + return(0); } - c=ssl->cert; - - return(ssl_set_cert(c,x)); + return(ssl_set_cert(ssl->cert,x)); } -int SSL_use_certificate_file(ssl, file, type) -SSL *ssl; -char *file; -int type; +#ifndef OPENSSL_NO_STDIO +int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { int j; BIO *in; int ret=0; X509 *x=NULL; -#ifdef WIN16 - in=BIO_new(BIO_s_file_internal_w16()); -#else - in=BIO_new(BIO_s_file()); -#endif + in=BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB); @@ -122,7 +98,6 @@ int type; if (BIO_read_filename(in,file) <= 0) { - SYSerr(SYS_F_FOPEN,errno); SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB); goto end; } @@ -134,7 +109,7 @@ int type; else if (type == SSL_FILETYPE_PEM) { j=ERR_R_PEM_LIB; - x=PEM_read_bio_X509(in,NULL,ssl->ctx->default_passwd_callback); + x=PEM_read_bio_X509(in,NULL,ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata); } else { @@ -154,11 +129,9 @@ end: if (in != NULL) BIO_free(in); return(ret); } +#endif -int SSL_use_certificate_ASN1(ssl, len, d) -SSL *ssl; -int len; -unsigned char *d; +int SSL_use_certificate_ASN1(SSL *ssl, unsigned char *d, int len) { X509 *x; int ret; @@ -175,12 +148,9 @@ unsigned char *d; return(ret); } -#ifndef NO_RSA -int SSL_use_RSAPrivateKey(ssl, rsa) -SSL *ssl; -RSA *rsa; +#ifndef OPENSSL_NO_RSA +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) { - CERT *c; EVP_PKEY *pkey; int ret; @@ -189,37 +159,27 @@ RSA *rsa; SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER); return(0); } - - if ((ssl->cert == NULL) || (ssl->cert == ssl->ctx->default_cert)) - { - c=ssl_cert_new(); - if (c == NULL) - { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE); - return(0); - } - if (ssl->cert != NULL) ssl_cert_free(ssl->cert); - ssl->cert=c; + if (!ssl_cert_inst(&ssl->cert)) + { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE); + return(0); } - c=ssl->cert; if ((pkey=EVP_PKEY_new()) == NULL) { SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY,ERR_R_EVP_LIB); return(0); } - CRYPTO_add(&rsa->references,1,CRYPTO_LOCK_RSA); + RSA_up_ref(rsa); EVP_PKEY_assign_RSA(pkey,rsa); - ret=ssl_set_pkey(c,pkey); + ret=ssl_set_pkey(ssl->cert,pkey); EVP_PKEY_free(pkey); return(ret); } #endif -static int ssl_set_pkey(c,pkey) -CERT *c; -EVP_PKEY *pkey; +static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) { int i,ok=0,bad=0; @@ -232,7 +192,22 @@ EVP_PKEY *pkey; if (c->pkeys[i].x509 != NULL) { - if (!X509_check_private_key(c->pkeys[i].x509,pkey)) + EVP_PKEY *pktmp; + pktmp = X509_get_pubkey(c->pkeys[i].x509); + EVP_PKEY_copy_parameters(pktmp,pkey); + EVP_PKEY_free(pktmp); + ERR_clear_error(); + +#ifndef OPENSSL_NO_RSA + /* Don't check the public/private key, this is mostly + * for smart cards. */ + if ((pkey->type == EVP_PKEY_RSA) && + (RSA_flags(pkey->pkey.rsa) & + RSA_METHOD_FLAG_NO_CHECK)) + ok=1; + else +#endif + if (!X509_check_private_key(c->pkeys[i].x509,pkey)) { if ((i == SSL_PKEY_DH_RSA) || (i == SSL_PKEY_DH_DSA)) { @@ -276,21 +251,15 @@ EVP_PKEY *pkey; return(1); } -#ifndef NO_RSA -int SSL_use_RSAPrivateKey_file(ssl, file, type) -SSL *ssl; -char *file; -int type; +#ifndef OPENSSL_NO_RSA +#ifndef OPENSSL_NO_STDIO +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) { int j,ret=0; BIO *in; RSA *rsa=NULL; -#ifdef WIN16 - in=BIO_new(BIO_s_file_internal_w16()); -#else - in=BIO_new(BIO_s_file()); -#endif + in=BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,ERR_R_BUF_LIB); @@ -299,7 +268,6 @@ int type; if (BIO_read_filename(in,file) <= 0) { - SYSerr(SYS_F_FOPEN,errno); SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE,ERR_R_SYS_LIB); goto end; } @@ -312,7 +280,7 @@ int type; { j=ERR_R_PEM_LIB; rsa=PEM_read_bio_RSAPrivateKey(in,NULL, - ssl->ctx->default_passwd_callback); + ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata); } else { @@ -330,14 +298,12 @@ end: if (in != NULL) BIO_free(in); return(ret); } +#endif -int SSL_use_RSAPrivateKey_ASN1(ssl,d,len) -SSL *ssl; -unsigned char *d; -long len; +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len) { int ret; - unsigned char *p; + const unsigned char *p; RSA *rsa; p=d; @@ -351,13 +317,10 @@ long len; RSA_free(rsa); return(ret); } -#endif /* !NO_RSA */ +#endif /* !OPENSSL_NO_RSA */ -int SSL_use_PrivateKey(ssl, pkey) -SSL *ssl; -EVP_PKEY *pkey; +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { - CERT *c; int ret; if (pkey == NULL) @@ -365,38 +328,23 @@ EVP_PKEY *pkey; SSLerr(SSL_F_SSL_USE_PRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER); return(0); } - - if ((ssl->cert == NULL) || (ssl->cert == ssl->ctx->default_cert)) - { - c=ssl_cert_new(); - if (c == NULL) - { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE); - return(0); - } - if (ssl->cert != NULL) ssl_cert_free(ssl->cert); - ssl->cert=c; + if (!ssl_cert_inst(&ssl->cert)) + { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE); + return(0); } - c=ssl->cert; - - ret=ssl_set_pkey(c,pkey); + ret=ssl_set_pkey(ssl->cert,pkey); return(ret); } -int SSL_use_PrivateKey_file(ssl, file, type) -SSL *ssl; -char *file; -int type; +#ifndef OPENSSL_NO_STDIO +int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) { int j,ret=0; BIO *in; EVP_PKEY *pkey=NULL; -#ifdef WIN16 - in=BIO_new(BIO_s_file_internal_w16()); -#else - in=BIO_new(BIO_s_file()); -#endif + in=BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_BUF_LIB); @@ -405,7 +353,6 @@ int type; if (BIO_read_filename(in,file) <= 0) { - SYSerr(SYS_F_FOPEN,errno); SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB); goto end; } @@ -413,7 +360,7 @@ int type; { j=ERR_R_PEM_LIB; pkey=PEM_read_bio_PrivateKey(in,NULL, - ssl->ctx->default_passwd_callback); + ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata); } else { @@ -431,12 +378,9 @@ end: if (in != NULL) BIO_free(in); return(ret); } +#endif -int SSL_use_PrivateKey_ASN1(type,ssl,d,len) -int type; -SSL *ssl; -unsigned char *d; -long len; +int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, unsigned char *d, long len) { int ret; unsigned char *p; @@ -454,36 +398,22 @@ long len; return(ret); } -int SSL_CTX_use_certificate(ctx, x) -SSL_CTX *ctx; -X509 *x; +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) { - CERT *c; - if (x == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_PASSED_NULL_PARAMETER); return(0); } - - if (ctx->default_cert == NULL) + if (!ssl_cert_inst(&ctx->cert)) { - c=ssl_cert_new(); - if (c == NULL) - { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE); - return(0); - } - ctx->default_cert=c; + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE,ERR_R_MALLOC_FAILURE); + return(0); } - c=ctx->default_cert; - - return(ssl_set_cert(c,x)); + return(ssl_set_cert(ctx->cert, x)); } -static int ssl_set_cert(c,x) -CERT *c; -X509 *x; +static int ssl_set_cert(CERT *c, X509 *x) { EVP_PKEY *pkey; int i,ok=0,bad=0; @@ -491,18 +421,32 @@ X509 *x; pkey=X509_get_pubkey(x); if (pkey == NULL) { - SSLerr(SSL_F_SSL_SET_PKEY,SSL_R_X509_LIB); + SSLerr(SSL_F_SSL_SET_CERT,SSL_R_X509_LIB); return(0); } i=ssl_cert_type(x,pkey); if (i < 0) { - SSLerr(SSL_F_SSL_SET_PKEY,SSL_R_UNKNOWN_CERTIFICATE_TYPE); + SSLerr(SSL_F_SSL_SET_CERT,SSL_R_UNKNOWN_CERTIFICATE_TYPE); + EVP_PKEY_free(pkey); return(0); } if (c->pkeys[i].privatekey != NULL) + { + EVP_PKEY_copy_parameters(pkey,c->pkeys[i].privatekey); + ERR_clear_error(); + +#ifndef OPENSSL_NO_RSA + /* Don't check the public/private key, this is mostly + * for smart cards. */ + if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) && + (RSA_flags(c->pkeys[i].privatekey->pkey.rsa) & + RSA_METHOD_FLAG_NO_CHECK)) + ok=1; + else +#endif { if (!X509_check_private_key(x,c->pkeys[i].privatekey)) { @@ -527,10 +471,12 @@ X509 *x; } else ok=1; + } /* OPENSSL_NO_RSA */ } else ok=1; + EVP_PKEY_free(pkey); if (bad) { EVP_PKEY_free(c->pkeys[i].privatekey); @@ -547,21 +493,15 @@ X509 *x; return(1); } -int SSL_CTX_use_certificate_file(ctx, file, type) -SSL_CTX *ctx; -char *file; -int type; +#ifndef OPENSSL_NO_STDIO +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) { int j; BIO *in; int ret=0; X509 *x=NULL; -#ifdef WIN16 - in=BIO_new(BIO_s_file_internal_w16()); -#else - in=BIO_new(BIO_s_file()); -#endif + in=BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB); @@ -570,7 +510,6 @@ int type; if (BIO_read_filename(in,file) <= 0) { - SYSerr(SYS_F_FOPEN,errno); SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB); goto end; } @@ -582,7 +521,7 @@ int type; else if (type == SSL_FILETYPE_PEM) { j=ERR_R_PEM_LIB; - x=PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback); + x=PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata); } else { @@ -602,11 +541,9 @@ end: if (in != NULL) BIO_free(in); return(ret); } +#endif -int SSL_CTX_use_certificate_ASN1(ctx, len, d) -SSL_CTX *ctx; -int len; -unsigned char *d; +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, unsigned char *d) { X509 *x; int ret; @@ -623,13 +560,10 @@ unsigned char *d; return(ret); } -#ifndef NO_RSA -int SSL_CTX_use_RSAPrivateKey(ctx, rsa) -SSL_CTX *ctx; -RSA *rsa; +#ifndef OPENSSL_NO_RSA +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) { int ret; - CERT *c; EVP_PKEY *pkey; if (rsa == NULL) @@ -637,46 +571,33 @@ RSA *rsa; SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER); return(0); } - if (ctx->default_cert == NULL) + if (!ssl_cert_inst(&ctx->cert)) { - c=ssl_cert_new(); - if (c == NULL) - { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE); - return(0); - } - ctx->default_cert=c; + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_MALLOC_FAILURE); + return(0); } - c=ctx->default_cert; - if ((pkey=EVP_PKEY_new()) == NULL) { SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY,ERR_R_EVP_LIB); return(0); } - CRYPTO_add(&rsa->references,1,CRYPTO_LOCK_RSA); + RSA_up_ref(rsa); EVP_PKEY_assign_RSA(pkey,rsa); - ret=ssl_set_pkey(c,pkey); + ret=ssl_set_pkey(ctx->cert, pkey); EVP_PKEY_free(pkey); return(ret); } -int SSL_CTX_use_RSAPrivateKey_file(ctx, file, type) -SSL_CTX *ctx; -char *file; -int type; +#ifndef OPENSSL_NO_STDIO +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) { int j,ret=0; BIO *in; RSA *rsa=NULL; -#ifdef WIN16 - in=BIO_new(BIO_s_file_internal_w16()); -#else - in=BIO_new(BIO_s_file()); -#endif + in=BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,ERR_R_BUF_LIB); @@ -685,7 +606,6 @@ int type; if (BIO_read_filename(in,file) <= 0) { - SYSerr(SYS_F_FOPEN,errno); SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE,ERR_R_SYS_LIB); goto end; } @@ -698,7 +618,7 @@ int type; { j=ERR_R_PEM_LIB; rsa=PEM_read_bio_RSAPrivateKey(in,NULL, - ctx->default_passwd_callback); + ctx->default_passwd_callback,ctx->default_passwd_callback_userdata); } else { @@ -716,14 +636,12 @@ end: if (in != NULL) BIO_free(in); return(ret); } +#endif -int SSL_CTX_use_RSAPrivateKey_ASN1(ctx,d,len) -SSL_CTX *ctx; -unsigned char *d; -long len; +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, unsigned char *d, long len) { int ret; - unsigned char *p; + const unsigned char *p; RSA *rsa; p=d; @@ -737,49 +655,31 @@ long len; RSA_free(rsa); return(ret); } -#endif /* !NO_RSA */ +#endif /* !OPENSSL_NO_RSA */ -int SSL_CTX_use_PrivateKey(ctx, pkey) -SSL_CTX *ctx; -EVP_PKEY *pkey; +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { - CERT *c; - if (pkey == NULL) { SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY,ERR_R_PASSED_NULL_PARAMETER); return(0); } - - if (ctx->default_cert == NULL) + if (!ssl_cert_inst(&ctx->cert)) { - c=ssl_cert_new(); - if (c == NULL) - { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE); - return(0); - } - ctx->default_cert=c; + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY,ERR_R_MALLOC_FAILURE); + return(0); } - c=ctx->default_cert; - - return(ssl_set_pkey(c,pkey)); + return(ssl_set_pkey(ctx->cert,pkey)); } -int SSL_CTX_use_PrivateKey_file(ctx, file, type) -SSL_CTX *ctx; -char *file; -int type; +#ifndef OPENSSL_NO_STDIO +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) { int j,ret=0; BIO *in; EVP_PKEY *pkey=NULL; -#ifdef WIN16 - in=BIO_new(BIO_s_file_internal_w16()); -#else - in=BIO_new(BIO_s_file()); -#endif + in=BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,ERR_R_BUF_LIB); @@ -788,7 +688,6 @@ int type; if (BIO_read_filename(in,file) <= 0) { - SYSerr(SYS_F_FOPEN,errno); SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB); goto end; } @@ -796,7 +695,7 @@ int type; { j=ERR_R_PEM_LIB; pkey=PEM_read_bio_PrivateKey(in,NULL, - ctx->default_passwd_callback); + ctx->default_passwd_callback,ctx->default_passwd_callback_userdata); } else { @@ -814,12 +713,10 @@ end: if (in != NULL) BIO_free(in); return(ret); } +#endif -int SSL_CTX_use_PrivateKey_ASN1(type,ctx,d,len) -int type; -SSL_CTX *ctx; -unsigned char *d; -long len; +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, unsigned char *d, + long len) { int ret; unsigned char *p; @@ -838,3 +735,81 @@ long len; } +#ifndef OPENSSL_NO_STDIO +/* Read a file that contains our certificate in "PEM" format, + * possibly followed by a sequence of CA certificates that should be + * sent to the peer in the Certificate message. + */ +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) + { + BIO *in; + int ret=0; + X509 *x=NULL; + + in=BIO_new(BIO_s_file_internal()); + if (in == NULL) + { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in,file) <= 0) + { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_SYS_LIB); + goto end; + } + + x=PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata); + if (x == NULL) + { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_PEM_LIB); + goto end; + } + + ret=SSL_CTX_use_certificate(ctx,x); + if (ERR_peek_error() != 0) + ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */ + if (ret) + { + /* If we could set up our certificate, now proceed to + * the CA certificates. + */ + X509 *ca; + int r; + unsigned long err; + + if (ctx->extra_certs != NULL) + { + sk_X509_pop_free(ctx->extra_certs, X509_free); + ctx->extra_certs = NULL; + } + + while ((ca = PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata)) + != NULL) + { + r = SSL_CTX_add_extra_chain_cert(ctx, ca); + if (!r) + { + X509_free(ca); + ret = 0; + goto end; + } + /* Note that we must not free r if it was successfully + * added to the chain (while we must free the main + * certificate, since its reference count is increased + * by SSL_CTX_use_certificate). */ + } + /* When the while loop ends, it's usually just EOF. */ + err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) + (void)ERR_get_error(); + else + ret = 0; /* some real error */ + } + +end: + if (x != NULL) X509_free(x); + if (in != NULL) BIO_free(in); + return(ret); + } +#endif