/** exit with ssl error related to a file path */ static void ssl_path_err(const char* s, const char *path) { unsigned long err; err = ERR_peek_error(); if (ERR_GET_LIB(err) == ERR_LIB_SYS && (ERR_GET_FUNC(err) == SYS_F_FOPEN || ERR_GET_FUNC(err) == SYS_F_FREAD) ) { fprintf(stderr, "error: %s\n%s: %s\n", s, path, ERR_reason_error_string(err)); exit(1); } else { ssl_err(s); } }
/** * Fetch OpenSSL error code and generate a string interpretation of it. * * @param[out] buf buffer to put string into * @param[in] buflen size of buffer * * @returns buf **/ gchar * z_ssl_get_error_str(gchar *buf, int buflen) { const char *ls, *fs, *rs; unsigned long e, l, f, r; unsigned long new_error = 0; gint count = -1; do { e = new_error; new_error= ERR_get_error(); ++count; } while (new_error); l = ERR_GET_LIB(e); f = ERR_GET_FUNC(e); r = ERR_GET_REASON(e); ls = ERR_lib_error_string(e); fs = ERR_func_error_string(e); rs = ERR_reason_error_string(e); if (count) g_snprintf(buf, buflen, "error:%08lX:%s:lib(%lu):%s:func(%lu):%s:reason(%lu), supressed %d messages", e, ls ? ls : "(null)", l, fs ? fs : "(null)", f, rs ? rs : "(null)", r, count); else g_snprintf(buf, buflen, "error:%08lX:%s:lib(%lu):%s:func(%lu):%s:reason(%lu)", e, ls ? ls : "(null)", l, fs ? fs : "(null)", f, rs ? rs : "(null)", r); return buf; }
static unsigned long err_string_data_hash(const ERR_STRING_DATA *a) { unsigned long ret, l; l = a->error; ret = l ^ ERR_GET_LIB(l) ^ ERR_GET_FUNC(l); return (ret ^ ret % 19 * 13); }
/* static unsigned long err_hash(ERR_STRING_DATA *a) */ static unsigned long err_hash(const void *a_void) { unsigned long ret,l; l=((const ERR_STRING_DATA *)a_void)->error; ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l); return(ret^ret%19*13); }
const char *ERR_func_error_string(unsigned long e) { ERR_STRING_DATA d,*p; unsigned long l,f; err_fns_check(); l=ERR_GET_LIB(e); f=ERR_GET_FUNC(e); d.error=ERR_PACK(l,f,0); p=ERRFN(err_get_item)(&d); return((p == NULL)?NULL:p->string); }
const char *ERR_func_error_string(unsigned long e) { ERR_STRING_DATA d, *p; unsigned long l, f; CRYPTO_THREAD_run_once(&err_string_init, do_err_strings_init); l = ERR_GET_LIB(e); f = ERR_GET_FUNC(e); d.error = ERR_PACK(l, f, 0); p = int_err_get_item(&d); return ((p == NULL) ? NULL : p->string); }
void ERR_error_string_n(unsigned long e, char *buf, size_t len) { char lsbuf[64], fsbuf[64], rsbuf[64]; const char *ls, *fs, *rs; unsigned long l, f, r; if (len == 0) return; l = ERR_GET_LIB(e); f = ERR_GET_FUNC(e); r = ERR_GET_REASON(e); ls = ERR_lib_error_string(e); fs = ERR_func_error_string(e); rs = ERR_reason_error_string(e); if (ls == NULL) BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l); if (fs == NULL) BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f); if (rs == NULL) BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r); BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls ? ls : lsbuf, fs ? fs : fsbuf, rs ? rs : rsbuf); if (strlen(buf) == len - 1) { /* * output may be truncated; make sure we always have 5 * colon-separated fields, i.e. 4 colons ... */ #define NUM_COLONS 4 if (len > NUM_COLONS) { /* ... if possible */ int i; char *s = buf; for (i = 0; i < NUM_COLONS; i++) { char *colon = strchr(s, ':'); if (colon == NULL || colon > &buf[len - 1] - NUM_COLONS + i) { /* * set colon no. i at last possible position (buf[len-1] * is the terminating 0) */ colon = &buf[len - 1] - NUM_COLONS + i; *colon = ':'; } s = colon + 1; } } } }
const char *ERR_func_error_string(unsigned long e) { ERR_STRING_DATA d, *p; unsigned long l, f; if (!RUN_ONCE(&err_string_init, do_err_strings_init)) { return NULL; } l = ERR_GET_LIB(e); f = ERR_GET_FUNC(e); d.error = ERR_PACK(l, f, 0); p = int_err_get_item(&d); return ((p == NULL) ? NULL : p->string); }
const char *ERR_func_error_string(unsigned long e) { ERR_STRING_DATA d,*p=NULL; unsigned long l,f; l=ERR_GET_LIB(e); f=ERR_GET_FUNC(e); CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH); if (error_hash != NULL) { d.error=ERR_PACK(l,f,0); p=(ERR_STRING_DATA *)lh_retrieve(error_hash,&d); } CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH); return((p == NULL)?NULL:p->string); }
/* BAD for multi-threaded, uses a local buffer if ret == NULL */ char *ERR_error_string(unsigned long e, char *ret) { #ifdef NO_ERR if(ret != NULL) { strcpy(ret, "No Error String Info."); } return "No Error String info."; #else static char buf[256]; const char *ls,*fs,*rs; unsigned long l,f,r; int i; l=ERR_GET_LIB(e); f=ERR_GET_FUNC(e); r=ERR_GET_REASON(e); ls=ERR_lib_error_string(e); fs=ERR_func_error_string(e); rs=ERR_reason_error_string(e); if (ret == NULL) ret=buf; sprintf(&(ret[0]),"error:%08lX:",e); i=strlen(ret); if (ls == NULL) sprintf(&(ret[i]),":lib(%lu) ",l); else sprintf(&(ret[i]),"%s",ls); i=strlen(ret); if (fs == NULL) sprintf(&(ret[i]),":func(%lu) ",f); else sprintf(&(ret[i]),":%s",fs); i=strlen(ret); if (rs == NULL) sprintf(&(ret[i]),":reason(%lu)",r); else sprintf(&(ret[i]),":%s",rs); return(ret); #endif }
SISCertificateChain* makeChain(const char* certData, EVP_PKEY** publicKey) { BIO* in = BIO_new_mem_buf((void*) certData, -1); BIO* out = BIO_new(BIO_s_mem()); while (true) { X509* cert = PEM_read_bio_X509(in, NULL, NULL, NULL); if (!cert) { unsigned long err = ERR_peek_last_error(); int lib = ERR_GET_LIB(err); int func = ERR_GET_FUNC(err); int reason = ERR_GET_REASON(err); if (lib == ERR_LIB_PEM && func == PEM_F_PEM_READ_BIO && reason == PEM_R_NO_START_LINE) break; ERR_print_errors_fp(stderr); throw SignBadCert; } if (!*publicKey) *publicKey = X509_PUBKEY_get(X509_get_X509_PUBKEY(cert)); i2d_X509_bio(out, cert); X509_OBJECT obj; obj.type = X509_LU_X509; obj.data.x509 = cert; X509_OBJECT_free_contents(&obj); } BIO_free_all(in); char* ptr; long length = BIO_get_mem_data(out, &ptr); if (length <= 0) { fprintf(stderr, "Bad certificate file\n"); throw SignBadCert; } SISBlob* blob = new SISBlob((uint8_t*) ptr, length); BIO_free_all(out); return new SISCertificateChain(blob); }
static int is_pem_password_error(struct openconnect_info *vpninfo) { unsigned long err = ERR_peek_error(); openconnect_report_ssl_errors(vpninfo); #ifndef EVP_F_EVP_DECRYPTFINAL_EX #define EVP_F_EVP_DECRYPTFINAL_EX EVP_F_EVP_DECRYPTFINAL #endif /* If the user fat-fingered the passphrase, try again */ if (ERR_GET_LIB(err) == ERR_LIB_EVP && ERR_GET_FUNC(err) == EVP_F_EVP_DECRYPTFINAL_EX && ERR_GET_REASON(err) == EVP_R_BAD_DECRYPT) { vpn_progress(vpninfo, PRG_ERR, _("Loading private key failed (wrong passphrase?)\n")); ERR_clear_error(); return 1; } vpn_progress(vpninfo, PRG_ERR, _("Loading private key failed (see above errors)\n")); return 0; }
void ERR_error_string_n(unsigned long e, char *buf, size_t len) { char lsbuf[64], fsbuf[64], rsbuf[64]; const char *ls, *fs, *rs; unsigned long l, f, r; if (len == 0) return; l = ERR_GET_LIB(e); ls = ERR_lib_error_string(e); if (ls == NULL) { BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l); ls = lsbuf; } fs = ERR_func_error_string(e); f = ERR_GET_FUNC(e); if (fs == NULL) { BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f); fs = fsbuf; } rs = ERR_reason_error_string(e); r = ERR_GET_REASON(e); if (rs == NULL) { BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r); rs = rsbuf; } BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls, fs, rs); if (strlen(buf) == len - 1) { /* Didn't fit; use a minimal format. */ BIO_snprintf(buf, len, "err:%lx:%lx:%lx:%lx", e, l, f, r); } }
/// Translate network error to processor error void signalError( const boost::system::error_code& e ) { ConnectionHandler::NetworkSignal ns; std::string name; int errorcode = e.value(); #if defined(_WIN32) #ifdef WITH_SSL // Rewrite error code got for a missing SSL_shutdown to a connection reset // because on Windows SSL_shutdown may not be called: if (e.category() == boost::asio::error::get_ssl_category() && e.value() == ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ)) { LOG_DEBUG << "Connection terminated abruptly by client, got no SSL_shutdown(); " << "error: " << e.value() << ", category: " << e.category().name() << ", message: " << e.message(); errorcode = boost::asio::error::connection_reset; } #endif #endif switch( errorcode ) { case boost::asio::error::eof : ns = ConnectionHandler::END_OF_FILE; name = "EOF"; break; case boost::asio::error::operation_aborted : ns = ConnectionHandler::OPERATION_CANCELLED; name = "OPERATION CANCELLED"; break; case boost::asio::error::broken_pipe : ns = ConnectionHandler::BROKEN_PIPE; name = "BROKEN PIPE"; break; case boost::asio::error::connection_reset : ns = ConnectionHandler::CONNECTION_RESET; name = "CONNECTION RESET"; break; default: { std::string err = e.message(); #ifdef WITH_SSL if ( e.category() == boost::asio::error::get_ssl_category() ) { err = std::string( "(" ) + boost::lexical_cast< std::string >( ERR_GET_LIB( e.value() ) ) + ", " + boost::lexical_cast< std::string >( ERR_GET_FUNC( e.value() ) )+ ", " + boost::lexical_cast< std::string >( ERR_GET_REASON( e.value() ) ) + ")"; //ERR_PACK /* crypto/err/err.h */ char buf[ 128 ]; ::ERR_error_string_n( e.value(), buf, sizeof( buf ) ); err += buf; } #endif // WITH_SSL LOG_DEBUG << "Unknown error: " << e.value() << ", category: " << e.category().name() << ", message: " << err; ns = ConnectionHandler::UNKNOWN_ERROR; name = "UNKNOWN ERROR"; break; } } m_connHandler->signalOccured( ns ); LOG_DATA << "Signalled " << name << " to processor for connection to " << identifier(); }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int ret=1; RSA *rsa=NULL; int i,badops=0, sgckey=0; const EVP_CIPHER *enc=NULL; BIO *out=NULL; int informat,outformat,text=0,check=0,noout=0; int pubin = 0, pubout = 0; char *infile,*outfile,*prog; char *passargin = NULL, *passargout = NULL; char *passin = NULL, *passout = NULL; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif int modulus=0; apps_startup(); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; infile=NULL; outfile=NULL; informat=FORMAT_PEM; outformat=FORMAT_PEM; prog=argv[0]; argc--; argv++; while (argc >= 1) { if (strcmp(*argv,"-inform") == 0) { if (--argc < 1) goto bad; informat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-outform") == 0) { if (--argc < 1) goto bad; outformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-in") == 0) { if (--argc < 1) goto bad; infile= *(++argv); } else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } else if (strcmp(*argv,"-passin") == 0) { if (--argc < 1) goto bad; passargin= *(++argv); } else if (strcmp(*argv,"-passout") == 0) { if (--argc < 1) goto bad; passargout= *(++argv); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } #endif else if (strcmp(*argv,"-sgckey") == 0) sgckey=1; else if (strcmp(*argv,"-pubin") == 0) pubin=1; else if (strcmp(*argv,"-pubout") == 0) pubout=1; else if (strcmp(*argv,"-noout") == 0) noout=1; else if (strcmp(*argv,"-text") == 0) text=1; else if (strcmp(*argv,"-modulus") == 0) modulus=1; else if (strcmp(*argv,"-check") == 0) check=1; else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL) { BIO_printf(bio_err,"unknown option %s\n",*argv); badops=1; break; } argc--; argv++; } if (badops) { bad: BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog); BIO_printf(bio_err,"where options are\n"); BIO_printf(bio_err," -inform arg input format - one of DER NET PEM\n"); BIO_printf(bio_err," -outform arg output format - one of DER NET PEM\n"); BIO_printf(bio_err," -in arg input file\n"); BIO_printf(bio_err," -sgckey Use IIS SGC key format\n"); BIO_printf(bio_err," -passin arg input file pass phrase source\n"); BIO_printf(bio_err," -out arg output file\n"); BIO_printf(bio_err," -passout arg output file pass phrase source\n"); BIO_printf(bio_err," -des encrypt PEM output with cbc des\n"); BIO_printf(bio_err," -des3 encrypt PEM output with ede cbc des using 168 bit key\n"); #ifndef OPENSSL_NO_SEED BIO_printf(bio_err," -seed encrypt PEM output with cbc seed\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf(bio_err," -aes128, -aes192, -aes256\n"); BIO_printf(bio_err," encrypt PEM output with cbc aes\n"); #endif #ifndef OPENSSL_NO_CAMELLIA BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n"); BIO_printf(bio_err," encrypt PEM output with cbc camellia\n"); #endif BIO_printf(bio_err," -text print the key in text\n"); BIO_printf(bio_err," -noout don't print key out\n"); BIO_printf(bio_err," -modulus print the RSA key modulus\n"); BIO_printf(bio_err," -check verify key consistency\n"); BIO_printf(bio_err," -pubin expect a public key in input file\n"); BIO_printf(bio_err," -pubout output a public key\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); #endif goto end; } ERR_load_crypto_strings(); #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if(check && pubin) { BIO_printf(bio_err, "Only private keys can be checked\n"); goto end; } out=BIO_new(BIO_s_file()); { EVP_PKEY *pkey; if (pubin) pkey = load_pubkey(bio_err, infile, (informat == FORMAT_NETSCAPE && sgckey ? FORMAT_IISSGC : informat), 1, passin, e, "Public Key"); else pkey = load_key(bio_err, infile, (informat == FORMAT_NETSCAPE && sgckey ? FORMAT_IISSGC : informat), 1, passin, e, "Private Key"); if (pkey != NULL) rsa = pkey == NULL ? NULL : EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); } if (rsa == NULL) { ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out,outfile) <= 0) { perror(outfile); goto end; } } if (text) if (!RSA_print(out,rsa,0)) { perror(outfile); ERR_print_errors(bio_err); goto end; } if (modulus) { BIO_printf(out,"Modulus="); BN_print(out,rsa->n); BIO_printf(out,"\n"); } if (check) { int r = RSA_check_key(rsa); if (r == 1) BIO_printf(out,"RSA key ok\n"); else if (r == 0) { unsigned long err; while ((err = ERR_peek_error()) != 0 && ERR_GET_LIB(err) == ERR_LIB_RSA && ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY && ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) { BIO_printf(out, "RSA key error: %s\n", ERR_reason_error_string(err)); ERR_get_error(); /* remove e from error stack */ } } if (r == -1 || ERR_peek_error() != 0) /* should happen only if r == -1 */ { ERR_print_errors(bio_err); goto end; } } if (noout) { ret = 0; goto end; } BIO_printf(bio_err,"writing RSA key\n"); if (outformat == FORMAT_ASN1) { if(pubout || pubin) i=i2d_RSA_PUBKEY_bio(out,rsa); else i=i2d_RSAPrivateKey_bio(out,rsa); } #ifndef OPENSSL_NO_RC4 else if (outformat == FORMAT_NETSCAPE) { unsigned char *p,*pp; int size; i=1; size=i2d_RSA_NET(rsa,NULL,NULL, sgckey); if ((p=(unsigned char *)OPENSSL_malloc(size)) == NULL) { BIO_printf(bio_err,"Memory allocation failure\n"); goto end; } pp=p; i2d_RSA_NET(rsa,&p,NULL, sgckey); BIO_write(out,(char *)pp,size); OPENSSL_free(pp); } #endif else if (outformat == FORMAT_PEM) { if(pubout || pubin) i=PEM_write_bio_RSA_PUBKEY(out,rsa); else i=PEM_write_bio_RSAPrivateKey(out,rsa, enc,NULL,0,NULL,passout); } else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err,"unable to write key\n"); ERR_print_errors(bio_err); } else ret=0; end: if(out != NULL) BIO_free_all(out); if(rsa != NULL) RSA_free(rsa); if(passin) OPENSSL_free(passin); if(passout) OPENSSL_free(passout); apps_shutdown(); OPENSSL_EXIT(ret); }
static int ssl_need_client_cert(SSL *ssl, X509 **cert, EVP_PKEY **pkey) { serf_ssl_context_t *ctx = SSL_get_app_data(ssl); apr_status_t status; if (ctx->cached_cert) { *cert = ctx->cached_cert; *pkey = ctx->cached_cert_pw; return 1; } while (ctx->cert_callback) { const char *cert_path; apr_file_t *cert_file; BIO *bio; PKCS12 *p12; int i; int retrying_success = 0; if (ctx->cert_file_success) { status = APR_SUCCESS; cert_path = ctx->cert_file_success; ctx->cert_file_success = NULL; retrying_success = 1; } else { status = ctx->cert_callback(ctx->cert_userdata, &cert_path); } if (status || !cert_path) { break; } /* Load the x.509 cert file stored in PKCS12 */ status = apr_file_open(&cert_file, cert_path, APR_READ, APR_OS_DEFAULT, ctx->pool); if (status) { continue; } bio = BIO_new(&bio_file_method); bio->ptr = cert_file; ctx->cert_path = cert_path; p12 = d2i_PKCS12_bio(bio, NULL); apr_file_close(cert_file); i = PKCS12_parse(p12, NULL, pkey, cert, NULL); if (i == 1) { PKCS12_free(p12); ctx->cached_cert = *cert; ctx->cached_cert_pw = *pkey; if (!retrying_success && ctx->cert_cache_pool) { const char *c; c = apr_pstrdup(ctx->cert_cache_pool, ctx->cert_path); apr_pool_userdata_setn(c, "serf:ssl:cert", apr_pool_cleanup_null, ctx->cert_cache_pool); } return 1; } else { int err = ERR_get_error(); ERR_clear_error(); if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 && ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) { if (ctx->cert_pw_callback) { const char *password; if (ctx->cert_pw_success) { status = APR_SUCCESS; password = ctx->cert_pw_success; ctx->cert_pw_success = NULL; } else { status = ctx->cert_pw_callback(ctx->cert_pw_userdata, ctx->cert_path, &password); } if (!status && password) { i = PKCS12_parse(p12, password, pkey, cert, NULL); if (i == 1) { PKCS12_free(p12); ctx->cached_cert = *cert; ctx->cached_cert_pw = *pkey; if (!retrying_success && ctx->cert_cache_pool) { const char *c; c = apr_pstrdup(ctx->cert_cache_pool, ctx->cert_path); apr_pool_userdata_setn(c, "serf:ssl:cert", apr_pool_cleanup_null, ctx->cert_cache_pool); } if (!retrying_success && ctx->cert_pw_cache_pool) { const char *c; c = apr_pstrdup(ctx->cert_pw_cache_pool, password); apr_pool_userdata_setn(c, "serf:ssl:certpw", apr_pool_cleanup_null, ctx->cert_pw_cache_pool); } return 1; } } } PKCS12_free(p12); return 0; } else { printf("OpenSSL cert error: %d %d %d\n", ERR_GET_LIB(err), ERR_GET_FUNC(err), ERR_GET_REASON(err)); PKCS12_free(p12); } } } return 0; }
void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) { char lib_buf[64], func_buf[64], reason_buf[64]; const char *lib_str, *func_str, *reason_str; unsigned lib, func, reason; if (len == 0) { return; } lib = ERR_GET_LIB(packed_error); func = ERR_GET_FUNC(packed_error); reason = ERR_GET_REASON(packed_error); lib_str = ERR_lib_error_string(packed_error); func_str = ERR_func_error_string(packed_error); reason_str = ERR_reason_error_string(packed_error); if (lib_str == NULL) { BIO_snprintf(lib_buf, sizeof(lib_buf), "lib(%u)", lib); lib_str = lib_buf; } if (func_str == NULL) { BIO_snprintf(func_buf, sizeof(func_buf), "func(%u)", func); func_str = func_buf; } if (reason_str == NULL) { BIO_snprintf(reason_buf, sizeof(reason_buf), "reason(%u)", reason); reason_str = reason_buf; } BIO_snprintf(buf, len, "error:%08" PRIx32 ":%s:%s:%s", packed_error, lib_str, func_str, reason_str); if (strlen(buf) == len - 1) { /* output may be truncated; make sure we always have 5 colon-separated * fields, i.e. 4 colons. */ static const unsigned num_colons = 4; unsigned i; char *s = buf; if (len <= num_colons) { /* In this situation it's not possible to ensure that the correct number * of colons are included in the output. */ return; } for (i = 0; i < num_colons; i++) { char *colon = strchr(s, ':'); char *last_pos = &buf[len - 1] - num_colons + i; if (colon == NULL || colon > last_pos) { /* set colon |i| at last possible position (buf[len-1] is the * terminating 0). If we're setting this colon, then all whole of the * rest of the string must be colons in order to have the correct * number. */ memset(last_pos, ':', num_colons - i); break; } s = colon + 1; } } }
const char *ERR_func_error_string(uint32_t packed_error) { return err_component_error_string( ERR_PACK(ERR_GET_LIB(packed_error), ERR_GET_FUNC(packed_error), 0)); }
static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12) { EVP_PKEY *pkey = NULL; X509 *cert = NULL; STACK_OF(X509) *ca; int ret = 0; char *pass; pass = vpninfo->cert_password; vpninfo->cert_password = NULL; retrypass: /* We do this every time round the loop, to work around a bug in OpenSSL < 1.0.0-beta2 -- where the stack at *ca will be freed when PKCS12_parse() returns an error, but *ca is left pointing to the freed memory. */ ca = NULL; if (!pass && request_passphrase(vpninfo, "openconnect_pkcs12", &pass, _("Enter PKCS#12 pass phrase:")) < 0) { PKCS12_free(p12); return -EINVAL; } if (!PKCS12_parse(p12, pass, &pkey, &cert, &ca)) { unsigned long err = ERR_peek_error(); openconnect_report_ssl_errors(vpninfo); if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 && ERR_GET_FUNC(err) == PKCS12_F_PKCS12_PARSE && ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) { vpn_progress(vpninfo, PRG_ERR, _("Parse PKCS#12 failed (wrong passphrase?)\n")); free(pass); pass = NULL; goto retrypass; } vpn_progress(vpninfo, PRG_ERR, _("Parse PKCS#12 failed (see above errors)\n")); PKCS12_free(p12); free(pass); return -EINVAL; } free(pass); if (cert) { char buf[200]; vpninfo->cert_x509 = cert; SSL_CTX_use_certificate(vpninfo->https_ctx, cert); X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf)); vpn_progress(vpninfo, PRG_INFO, _("Using client certificate '%s'\n"), buf); } else { vpn_progress(vpninfo, PRG_ERR, _("PKCS#12 contained no certificate!")); ret = -EINVAL; } if (pkey) { SSL_CTX_use_PrivateKey(vpninfo->https_ctx, pkey); EVP_PKEY_free(pkey); } else { vpn_progress(vpninfo, PRG_ERR, _("PKCS#12 contained no private key!")); ret = -EINVAL; } /* Only include supporting certificates which are actually necessary */ if (ca) { int i; next: for (i = 0; i < sk_X509_num(ca); i++) { X509 *cert2 = sk_X509_value(ca, i); if (X509_check_issued(cert2, cert) == X509_V_OK) { char buf[200]; if (cert2 == cert) break; if (X509_check_issued(cert2, cert2) == X509_V_OK) break; X509_NAME_oneline(X509_get_subject_name(cert2), buf, sizeof(buf)); vpn_progress(vpninfo, PRG_DEBUG, _("Extra cert from PKCS#12: '%s'\n"), buf); CRYPTO_add(&cert2->references, 1, CRYPTO_LOCK_X509); SSL_CTX_add_extra_chain_cert(vpninfo->https_ctx, cert2); cert = cert2; goto next; } } sk_X509_pop_free(ca, X509_free); } PKCS12_free(p12); return ret; }
int rsa_main(int argc, char **argv) { ENGINE *e = NULL; BIO *out = NULL; RSA *rsa = NULL; const EVP_CIPHER *enc = NULL; char *infile = NULL, *outfile = NULL, *prog; char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL; int i; int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, check = 0; int noout = 0, modulus = 0, pubin = 0, pubout = 0, pvk_encr = 2, ret = 1; OPTION_CHOICE o; prog = opt_init(argc, argv, rsa_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: #ifdef OPENSSL_NO_RC4 case OPT_PVK_STRONG: case OPT_PVK_WEAK: case OPT_PVK_NONE: #endif opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(rsa_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat)) goto opthelp; break; case OPT_OUT: outfile = opt_arg(); break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_PASSOUT: passoutarg = opt_arg(); break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_PUBIN: pubin = 1; break; case OPT_PUBOUT: pubout = 1; break; case OPT_RSAPUBKEY_IN: pubin = 2; break; case OPT_RSAPUBKEY_OUT: pubout = 2; break; #ifndef OPENSSL_NO_RC4 case OPT_PVK_STRONG: pvk_encr = 2; break; case OPT_PVK_WEAK: pvk_encr = 1; break; case OPT_PVK_NONE: pvk_encr = 0; break; #endif case OPT_NOOUT: noout = 1; break; case OPT_TEXT: text = 1; break; case OPT_MODULUS: modulus = 1; break; case OPT_CHECK: check = 1; break; case OPT_CIPHER: if (!opt_cipher(opt_unknown(), &enc)) goto opthelp; break; } } argc = opt_num_rest(); argv = opt_rest(); if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if (check && pubin) { BIO_printf(bio_err, "Only private keys can be checked\n"); goto end; } { EVP_PKEY *pkey; if (pubin) { int tmpformat = -1; if (pubin == 2) { if (informat == FORMAT_PEM) tmpformat = FORMAT_PEMRSA; else if (informat == FORMAT_ASN1) tmpformat = FORMAT_ASN1RSA; } else tmpformat = informat; pkey = load_pubkey(infile, tmpformat, 1, passin, e, "Public Key"); } else pkey = load_key(infile, informat, 1, passin, e, "Private Key"); if (pkey != NULL) rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); } if (rsa == NULL) { ERR_print_errors(bio_err); goto end; } out = bio_open_default(outfile, "w"); if (out == NULL) goto end; if (text) if (!RSA_print(out, rsa, 0)) { perror(outfile); ERR_print_errors(bio_err); goto end; } if (modulus) { BIO_printf(out, "Modulus="); BN_print(out, rsa->n); BIO_printf(out, "\n"); } if (check) { int r = RSA_check_key(rsa); if (r == 1) BIO_printf(out, "RSA key ok\n"); else if (r == 0) { unsigned long err; while ((err = ERR_peek_error()) != 0 && ERR_GET_LIB(err) == ERR_LIB_RSA && ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY && ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) { BIO_printf(out, "RSA key error: %s\n", ERR_reason_error_string(err)); ERR_get_error(); /* remove e from error stack */ } } /* should happen only if r == -1 */ if (r == -1 || ERR_peek_error() != 0) { ERR_print_errors(bio_err); goto end; } } if (noout) { ret = 0; goto end; } BIO_printf(bio_err, "writing RSA key\n"); if (outformat == FORMAT_ASN1) { if (pubout || pubin) { if (pubout == 2) i = i2d_RSAPublicKey_bio(out, rsa); else i = i2d_RSA_PUBKEY_bio(out, rsa); } else i = i2d_RSAPrivateKey_bio(out, rsa); } # ifndef OPENSSL_NO_RC4 else if (outformat == FORMAT_NETSCAPE) { unsigned char *p, *pp; int size; i = 1; size = i2d_RSA_NET(rsa, NULL, NULL, 0); if ((p = OPENSSL_malloc(size)) == NULL) { BIO_printf(bio_err, "Memory allocation failure\n"); goto end; } pp = p; i2d_RSA_NET(rsa, &p, NULL, 0); BIO_write(out, (char *)pp, size); OPENSSL_free(pp); } # endif else if (outformat == FORMAT_PEM) { if (pubout || pubin) { if (pubout == 2) i = PEM_write_bio_RSAPublicKey(out, rsa); else i = PEM_write_bio_RSA_PUBKEY(out, rsa); } else i = PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, NULL, passout); # if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { EVP_PKEY *pk; pk = EVP_PKEY_new(); EVP_PKEY_set1_RSA(pk, rsa); if (outformat == FORMAT_PVK) i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); else if (pubin || pubout) i = i2b_PublicKey_bio(out, pk); else i = i2b_PrivateKey_bio(out, pk); EVP_PKEY_free(pk); # endif } else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (i <= 0) { BIO_printf(bio_err, "unable to write key\n"); ERR_print_errors(bio_err); } else ret = 0; end: BIO_free_all(out); RSA_free(rsa); if (passin) OPENSSL_free(passin); if (passout) OPENSSL_free(passout); return (ret); }
int rsa_main(int argc, char **argv) { int ret = 1; RSA *rsa = NULL; int i; BIO *out = NULL; char *passin = NULL, *passout = NULL; if (single_execution) { if (pledge("stdio cpath wpath rpath tty", NULL) == -1) { perror("pledge"); exit(1); } } memset(&rsa_config, 0, sizeof(rsa_config)); rsa_config.pvk_encr = 2; rsa_config.informat = FORMAT_PEM; rsa_config.outformat = FORMAT_PEM; if (options_parse(argc, argv, rsa_options, NULL, NULL) != 0) { rsa_usage(); goto end; } if (!app_passwd(bio_err, rsa_config.passargin, rsa_config.passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if (rsa_config.check && rsa_config.pubin) { BIO_printf(bio_err, "Only private keys can be checked\n"); goto end; } out = BIO_new(BIO_s_file()); { EVP_PKEY *pkey; if (rsa_config.pubin) { int tmpformat = -1; if (rsa_config.pubin == 2) { if (rsa_config.informat == FORMAT_PEM) tmpformat = FORMAT_PEMRSA; else if (rsa_config.informat == FORMAT_ASN1) tmpformat = FORMAT_ASN1RSA; } else if (rsa_config.informat == FORMAT_NETSCAPE && rsa_config.sgckey) tmpformat = FORMAT_IISSGC; else tmpformat = rsa_config.informat; pkey = load_pubkey(bio_err, rsa_config.infile, tmpformat, 1, passin, "Public Key"); } else pkey = load_key(bio_err, rsa_config.infile, (rsa_config.informat == FORMAT_NETSCAPE && rsa_config.sgckey ? FORMAT_IISSGC : rsa_config.informat), 1, passin, "Private Key"); if (pkey != NULL) rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); } if (rsa == NULL) { ERR_print_errors(bio_err); goto end; } if (rsa_config.outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); } else { if (BIO_write_filename(out, rsa_config.outfile) <= 0) { perror(rsa_config.outfile); goto end; } } if (rsa_config.text) if (!RSA_print(out, rsa, 0)) { perror(rsa_config.outfile); ERR_print_errors(bio_err); goto end; } if (rsa_config.modulus) { BIO_printf(out, "Modulus="); BN_print(out, rsa->n); BIO_printf(out, "\n"); } if (rsa_config.check) { int r = RSA_check_key(rsa); if (r == 1) BIO_printf(out, "RSA key ok\n"); else if (r == 0) { unsigned long err; while ((err = ERR_peek_error()) != 0 && ERR_GET_LIB(err) == ERR_LIB_RSA && ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY && ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) { BIO_printf(out, "RSA key error: %s\n", ERR_reason_error_string(err)); ERR_get_error(); /* remove e from error * stack */ } } if (r == -1 || ERR_peek_error() != 0) { /* should happen only if * r == -1 */ ERR_print_errors(bio_err); goto end; } } if (rsa_config.noout) { ret = 0; goto end; } BIO_printf(bio_err, "writing RSA key\n"); if (rsa_config.outformat == FORMAT_ASN1) { if (rsa_config.pubout || rsa_config.pubin) { if (rsa_config.pubout == 2) i = i2d_RSAPublicKey_bio(out, rsa); else i = i2d_RSA_PUBKEY_bio(out, rsa); } else i = i2d_RSAPrivateKey_bio(out, rsa); } #ifndef OPENSSL_NO_RC4 else if (rsa_config.outformat == FORMAT_NETSCAPE) { unsigned char *p, *pp; int size; i = 1; size = i2d_RSA_NET(rsa, NULL, NULL, rsa_config.sgckey); if ((p = malloc(size)) == NULL) { BIO_printf(bio_err, "Memory allocation failure\n"); goto end; } pp = p; i2d_RSA_NET(rsa, &p, NULL, rsa_config.sgckey); BIO_write(out, (char *) pp, size); free(pp); } #endif else if (rsa_config.outformat == FORMAT_PEM) { if (rsa_config.pubout || rsa_config.pubin) { if (rsa_config.pubout == 2) i = PEM_write_bio_RSAPublicKey(out, rsa); else i = PEM_write_bio_RSA_PUBKEY(out, rsa); } else i = PEM_write_bio_RSAPrivateKey(out, rsa, rsa_config.enc, NULL, 0, NULL, passout); #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) } else if (rsa_config.outformat == FORMAT_MSBLOB || rsa_config.outformat == FORMAT_PVK) { EVP_PKEY *pk; pk = EVP_PKEY_new(); EVP_PKEY_set1_RSA(pk, rsa); if (rsa_config.outformat == FORMAT_PVK) i = i2b_PVK_bio(out, pk, rsa_config.pvk_encr, 0, passout); else if (rsa_config.pubin || rsa_config.pubout) i = i2b_PublicKey_bio(out, pk); else i = i2b_PrivateKey_bio(out, pk); EVP_PKEY_free(pk); #endif } else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (i <= 0) { BIO_printf(bio_err, "unable to write key\n"); ERR_print_errors(bio_err); } else ret = 0; end: BIO_free_all(out); RSA_free(rsa); free(passin); free(passout); return (ret); }
/** Perform a TLS/SSL handshake. This function will perform a TLS/SSL handshake. @param[in] Tls Pointer to the TLS object for handshake operation. @param[in] BufferIn Pointer to the most recently received TLS Handshake packet. @param[in] BufferInSize Packet size in bytes for the most recently received TLS Handshake packet. @param[out] BufferOut Pointer to the buffer to hold the built packet. @param[in, out] BufferOutSize Pointer to the buffer size in bytes. On input, it is the buffer size provided by the caller. On output, it is the buffer size in fact needed to contain the packet. @retval EFI_SUCCESS The required TLS packet is built successfully. @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: Tls is NULL. BufferIn is NULL but BufferInSize is NOT 0. BufferInSize is 0 but BufferIn is NOT NULL. BufferOutSize is NULL. BufferOut is NULL if *BufferOutSize is not zero. @retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the response packet. @retval EFI_ABORTED Something wrong during handshake. **/ EFI_STATUS EFIAPI TlsDoHandshake ( IN VOID *Tls, IN UINT8 *BufferIn, OPTIONAL IN UINTN BufferInSize, OPTIONAL OUT UINT8 *BufferOut, OPTIONAL IN OUT UINTN *BufferOutSize ) { TLS_CONNECTION *TlsConn; UINTN PendingBufferSize; INTN Ret; UINTN ErrorCode; TlsConn = (TLS_CONNECTION *) Tls; PendingBufferSize = 0; Ret = 1; if (TlsConn == NULL || \ TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \ BufferOutSize == NULL || \ (BufferIn == NULL && BufferInSize != 0) || \ (BufferIn != NULL && BufferInSize == 0) || \ (BufferOut == NULL && *BufferOutSize != 0)) { return EFI_INVALID_PARAMETER; } if(BufferIn == NULL && BufferInSize == 0) { // // If RequestBuffer is NULL and RequestSize is 0, and TLS session // status is EfiTlsSessionNotStarted, the TLS session will be initiated // and the response packet needs to be ClientHello. // PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio); if (PendingBufferSize == 0) { SSL_set_connect_state (TlsConn->Ssl); Ret = SSL_do_handshake (TlsConn->Ssl); PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio); } } else { PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio); if (PendingBufferSize == 0) { BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize); Ret = SSL_do_handshake (TlsConn->Ssl); PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio); } } if (Ret < 1) { Ret = SSL_get_error (TlsConn->Ssl, (int) Ret); if (Ret == SSL_ERROR_SSL || Ret == SSL_ERROR_SYSCALL || Ret == SSL_ERROR_ZERO_RETURN) { DEBUG (( DEBUG_ERROR, "%a SSL_HANDSHAKE_ERROR State=0x%x SSL_ERROR_%a\n", __FUNCTION__, SSL_get_state (TlsConn->Ssl), Ret == SSL_ERROR_SSL ? "SSL" : Ret == SSL_ERROR_SYSCALL ? "SYSCALL" : "ZERO_RETURN" )); DEBUG_CODE_BEGIN (); while (TRUE) { ErrorCode = ERR_get_error (); if (ErrorCode == 0) { break; } DEBUG (( DEBUG_ERROR, "%a ERROR 0x%x=L%x:F%x:R%x\n", __FUNCTION__, ErrorCode, ERR_GET_LIB (ErrorCode), ERR_GET_FUNC (ErrorCode), ERR_GET_REASON (ErrorCode) )); } DEBUG_CODE_END (); return EFI_ABORTED; } } if (PendingBufferSize > *BufferOutSize) { *BufferOutSize = PendingBufferSize; return EFI_BUFFER_TOO_SMALL; } if (PendingBufferSize > 0) { *BufferOutSize = BIO_read (TlsConn->OutBio, BufferOut, (UINT32) PendingBufferSize); } else { *BufferOutSize = 0; } return EFI_SUCCESS; }