int main(int argc, char *argv[]) { const char *cert_filename = "ecc_server.crt"; BIO *cert_bio = NULL; BIO *out_bio = NULL; X509 *cert = NULL; EVP_PKEY *pkey = NULL; int ret; OpenSSL_add_all_algorithms(); ERR_load_BIO_strings(); ERR_load_crypto_strings(); cert_bio = BIO_new(BIO_s_file()); out_bio = BIO_new_fp(stdout, BIO_NOCLOSE); ret = BIO_read_filename(cert_bio, cert_filename); if (!(cert = PEM_read_bio_X509(cert_bio, NULL, 0, NULL))) { BIO_printf(out_bio, "Error loading cert into memory\n"); exit(-1); } if ((pkey = X509_get_pubkey(cert)) == NULL) BIO_printf(out_bio, "Error getting public key from certificate\n"); if (pkey) { switch (EVP_PKEY_id(pkey)) { case EVP_PKEY_RSA: BIO_printf(out_bio, "%d bit RSA Key\n\n", EVP_PKEY_bits(pkey)); break; case EVP_PKEY_DSA: BIO_printf(out_bio, "%d bit DSA Key\n\n", EVP_PKEY_bits(pkey)); break; default: BIO_printf(out_bio, "%d bit non-RSA/DSA\n\n", EVP_PKEY_bits(pkey)); break; } } if (!PEM_write_bio_PUBKEY(out_bio, pkey)) BIO_printf(out_bio, "Error writing public key data in PEM format\n"); EVP_PKEY_free(pkey); X509_free(cert); BIO_free_all(cert_bio); BIO_free_all(out_bio); return 0; }
static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl) { #ifdef SSL_get_server_tmp_key /* Show ephemeral key information. */ EVP_PKEY *ephemeral_key = NULL; /* OPENSSL_NO_EC is for solaris 11.3 (2016), github ticket #598 */ #ifndef OPENSSL_NO_EC EC_KEY *ec_key = NULL; #endif char *ephemeral_key_algorithm = NULL; char *cname = NULL; int nid; g_return_if_fail(tls != NULL); g_return_if_fail(ssl != NULL); if (SSL_get_server_tmp_key(ssl, &ephemeral_key)) { switch (EVP_PKEY_id(ephemeral_key)) { case EVP_PKEY_DH: tls_rec_set_ephemeral_key_algorithm(tls, "DH"); tls_rec_set_ephemeral_key_size(tls, EVP_PKEY_bits(ephemeral_key)); break; #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: ec_key = EVP_PKEY_get1_EC_KEY(ephemeral_key); nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); EC_KEY_free(ec_key); cname = (char *)OBJ_nid2sn(nid); ephemeral_key_algorithm = g_strdup_printf("ECDH: %s", cname); tls_rec_set_ephemeral_key_algorithm(tls, ephemeral_key_algorithm); tls_rec_set_ephemeral_key_size(tls, EVP_PKEY_bits(ephemeral_key)); g_free_and_null(ephemeral_key_algorithm); break; #endif default: tls_rec_set_ephemeral_key_algorithm(tls, "Unknown"); tls_rec_set_ephemeral_key_size(tls, EVP_PKEY_bits(ephemeral_key)); break; } EVP_PKEY_free(ephemeral_key); } #endif /* SSL_get_server_tmp_key. */ }
void read_public_key(drown_ctx * dctx, char *filename) { // Read file FILE * fp = fopen(filename, "r"); MY_ASSERT(fp != NULL, "can't open certificate file"); // Read cert X509 *cert = PEM_read_X509(fp, NULL, NULL, NULL); MY_ASSERT(cert != NULL, "file is not a certificate"); // Read public key EVP_PKEY * pkey = X509_get_pubkey(cert); MY_ASSERT(pkey != NULL, "can't get public key from certificate"); // Check RSA key MY_ASSERT(pkey->type == EVP_PKEY_RSA, "public key is not RSA"); MY_ASSERT(EVP_PKEY_bits(pkey) == 2048, "only RSA-2048 is supported for now"); // Read RSA key RSA *rsa = EVP_PKEY_get1_RSA(pkey); // Copy the public key BN_copy(dctx->n, rsa->n); BN_copy(dctx->e, rsa->e); RSA_free(rsa); EVP_PKEY_free(pkey); X509_free(cert); fclose(fp); }
QString pki_key::length() { if (key->type == EVP_PKEY_DSA && key->pkey.dsa->p == NULL) { return QString("???"); } return QString("%1 bit").arg(EVP_PKEY_bits(key)); }
static isc_result_t opensslgost_fromdns(dst_key_t *key, isc_buffer_t *data) { isc_region_t r; EVP_PKEY *pkey = NULL; unsigned char der[37 + 64]; const unsigned char *p; isc_buffer_remainingregion(data, &r); if (r.length == 0) return (ISC_R_SUCCESS); if (r.length != 64) return (DST_R_INVALIDPUBLICKEY); memmove(der, gost_prefix, 37); memmove(der + 37, r.base, 64); isc_buffer_forward(data, 64); p = der; if (d2i_PUBKEY(&pkey, &p, (long) sizeof(der)) == NULL) return (dst__openssl_toresult2("d2i_PUBKEY", DST_R_OPENSSLFAILURE)); key->keydata.pkey = pkey; key->key_size = EVP_PKEY_bits(pkey); return (ISC_R_SUCCESS); }
/* rsa_ctx_to_pss converts EVP_PKEY_CTX in PSS mode into corresponding * algorithm parameter, suitable for setting as an AlgorithmIdentifier. */ static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) { const EVP_MD *sigmd, *mgf1md; RSA_PSS_PARAMS *pss = NULL; ASN1_STRING *os = NULL; EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); int saltlen, rv = 0; if (!EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) || !EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) || !EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) { goto err; } if (saltlen == -1) { saltlen = EVP_MD_size(sigmd); } else if (saltlen == -2) { saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) { saltlen--; } } else { goto err; } pss = RSA_PSS_PARAMS_new(); if (!pss) { goto err; } if (saltlen != 20) { pss->saltLength = ASN1_INTEGER_new(); if (!pss->saltLength || !ASN1_INTEGER_set(pss->saltLength, saltlen)) { goto err; } } if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) || !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) { goto err; } /* Finally create string with pss parameter encoding. */ if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) { goto err; } rv = 1; err: if (pss) { RSA_PSS_PARAMS_free(pss); } if (rv) { return os; } if (os) { ASN1_STRING_free(os); } return NULL; }
static isc_result_t opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; isc_mem_t *mctx = key->mctx; EVP_PKEY *pkey = NULL; const unsigned char *p; UNUSED(pub); /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_ECCGOST, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) return (ret); INSIST(priv.elements[0].tag == TAG_GOST_PRIVASN1); p = priv.elements[0].data; if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) priv.elements[0].length) == NULL) DST_RET(dst__openssl_toresult2("d2i_PrivateKey", DST_R_INVALIDPRIVATEKEY)); key->keydata.pkey = pkey; key->key_size = EVP_PKEY_bits(pkey); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); err: if (pkey != NULL) EVP_PKEY_free(pkey); opensslgost_destroy(key); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); }
static int openssl_pkey_bits(lua_State *L) { EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); lua_Integer ret = EVP_PKEY_bits(pkey); lua_pushinteger(L, ret); return 1; };
static PyObject * crypto_PKey_bits(crypto_PKeyObj *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":bits")) return NULL; return PyLong_FromLong(EVP_PKEY_bits(self->pkey)); }
int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { const EVP_MD *sigmd, *mgf1md; int saltlen; if (!EVP_PKEY_CTX_get_signature_md(ctx->pctx, &sigmd) || !EVP_PKEY_CTX_get_rsa_mgf1_md(ctx->pctx, &mgf1md) || !EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx->pctx, &saltlen)) { return 0; } EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(ctx->pctx); if (saltlen == -1) { saltlen = EVP_MD_size(sigmd); } else if (saltlen == -2) { saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) { saltlen--; } } else { return 0; } int ret = 0; ASN1_STRING *os = NULL; RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new(); if (!pss) { goto err; } if (saltlen != 20) { pss->saltLength = ASN1_INTEGER_new(); if (!pss->saltLength || !ASN1_INTEGER_set(pss->saltLength, saltlen)) { goto err; } } if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) || !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) { goto err; } /* Finally create string with pss parameter encoding. */ if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) { goto err; } X509_ALGOR_set0(algor, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os); os = NULL; ret = 1; err: RSA_PSS_PARAMS_free(pss); ASN1_STRING_free(os); return ret; }
int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, EVP_PKEY *private_key) { ctx->tlsext_channel_id_enabled = 1; if (EVP_PKEY_id(private_key) != EVP_PKEY_EC || EVP_PKEY_bits(private_key) != 256) { OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256); return 0; } EVP_PKEY_free(ctx->tlsext_channel_id_private); ctx->tlsext_channel_id_private = EVP_PKEY_up_ref(private_key); return 1; }
uint32_t get_certificate_keybits (EVP_PKEY *public_key) { /* In theory, we could use check_bitlen_dsa() and check_bitlen_rsa() */ uint32_t key_bits; switch (public_key->type) { case EVP_PKEY_RSA: verb("V: key type: EVP_PKEY_RSA"); key_bits = BN_num_bits(public_key->pkey.rsa->n); break; case EVP_PKEY_RSA2: verb("V: key type: EVP_PKEY_RSA2"); key_bits = BN_num_bits(public_key->pkey.rsa->n); break; case EVP_PKEY_DSA: verb("V: key type: EVP_PKEY_DSA"); key_bits = BN_num_bits(public_key->pkey.dsa->p); break; case EVP_PKEY_DSA1: verb("V: key type: EVP_PKEY_DSA1"); key_bits = BN_num_bits(public_key->pkey.dsa->p); break; case EVP_PKEY_DSA2: verb("V: key type: EVP_PKEY_DSA2"); key_bits = BN_num_bits(public_key->pkey.dsa->p); break; case EVP_PKEY_DSA3: verb("V: key type: EVP_PKEY_DSA3"); key_bits = BN_num_bits(public_key->pkey.dsa->p); break; case EVP_PKEY_DSA4: verb("V: key type: EVP_PKEY_DSA4"); key_bits = BN_num_bits(public_key->pkey.dsa->p); break; case EVP_PKEY_DH: verb("V: key type: EVP_PKEY_DH"); key_bits = BN_num_bits(public_key->pkey.dh->pub_key); break; case EVP_PKEY_EC: verb("V: key type: EVP_PKEY_EC"); key_bits = EVP_PKEY_bits(public_key); break; // Should we also care about EVP_PKEY_HMAC and EVP_PKEY_CMAC? default: key_bits = 0; die ("unknown public key type"); break; } verb ("V: keybits: %d", key_bits); return key_bits; }
int isns_dsasig_sign(isns_security_t *ctx, isns_principal_t *peer, buf_t *pdu, struct isns_authblk *blk) { static unsigned char signature[1024]; unsigned int sig_len = sizeof(signature); EVP_MD_CTX *md_ctx; EVP_PKEY *pkey; const BIGNUM *priv_key = NULL; int err; if ((pkey = peer->is_key) == NULL) return 0; if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DSA) { isns_debug_message( "Incompatible public key (spi=%s)\n", peer->is_name); return 0; } if (EVP_PKEY_size(pkey) > sizeof(signature)) { isns_error("isns_dsasig_sign: signature buffer too small\n"); return 0; } DSA_get0_key(EVP_PKEY_get0_DSA(pkey), NULL, &priv_key); if (priv_key == NULL) { isns_error("isns_dsasig_sign: oops, seems to be a public key\n"); return 0; } isns_debug_auth("Signing messages with spi=%s, DSA/%u\n", peer->is_name, EVP_PKEY_bits(pkey)); md_ctx = EVP_MD_CTX_new(); EVP_SignInit(md_ctx, EVP_dss1()); isns_message_digest(md_ctx, pdu, blk); err = EVP_SignFinal(md_ctx, signature, &sig_len, pkey); EVP_MD_CTX_free(md_ctx); if (err == 0) { isns_dsasig_report_errors("EVP_SignFinal failed", isns_error); return 0; } blk->iab_sig = signature; blk->iab_sig_len = sig_len; return 1; }
int ssl_print_tmp_key(BIO *out, SSL *s) { const char *cname; EVP_PKEY *pkey; EC_KEY *ec; int nid; if (!SSL_get_server_tmp_key(s, &pkey)) return 0; BIO_puts(out, "Server Temp Key: "); switch (EVP_PKEY_id(pkey)) { case EVP_PKEY_DH: BIO_printf(out, "DH, %d bits\n", EVP_PKEY_bits(pkey)); break; case EVP_PKEY_EC: ec = EVP_PKEY_get1_EC_KEY(pkey); nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); EC_KEY_free(ec); if ((cname = EC_curve_nid2nist(nid)) == NULL) cname = OBJ_nid2sn(nid); BIO_printf(out, "ECDH, %s, %d bits\n", cname, EVP_PKEY_bits(pkey)); break; default: BIO_printf(out, "%s, %d bits\n", OBJ_nid2sn(EVP_PKEY_id(pkey)), EVP_PKEY_bits(pkey)); } EVP_PKEY_free(pkey); return 1; }
static DH *dh_auto_cb(SSL *s, int is_export, int keylength) { EVP_PKEY *pk; int bits; pk = SSL_get_privatekey(s); if (!pk) return load_dh_buffer(&dh2048, file_dh2048); bits = EVP_PKEY_bits(pk); if (bits >= 3072) return load_dh_buffer(&dh4096, file_dh4096); if (bits >= 1536) return load_dh_buffer(&dh2048, file_dh2048); return load_dh_buffer(&dh1024, file_dh1024); }
//----------------START Get Private key-------------------------- EVP_PKEY* an_key_get_private_key_from_keypair (uint8_t *key_label) { const char cert_filestr[] = PRIVATE_KEY_LOCATION; EVP_PKEY *pkey; BIO* rsa_pub_bio = BIO_new_file(cert_filestr, "r"); pkey = PEM_read_bio_PrivateKey(rsa_pub_bio, NULL, NULL, NULL); if (pkey == NULL) { DEBUG_AN_LOG(AN_LOG_BS_EVENT, AN_DEBUG_INFO, NULL, "\n%sFailed to read private key from key pair",an_bs_event); return FALSE; } fprintf(stdout, "RSA Private Key: (%d bit)\n", EVP_PKEY_bits(pkey)); BIO_free(rsa_pub_bio); return(pkey); }
/** * Extract public key in PEM format. */ static int meth_pubkey(lua_State* L) { char* data; long bytes; int ret = 1; X509* cert = lsec_checkx509(L, 1); BIO *bio = BIO_new(BIO_s_mem()); EVP_PKEY *pkey = X509_get_pubkey(cert); if(PEM_write_bio_PUBKEY(bio, pkey)) { bytes = BIO_get_mem_data(bio, &data); if (bytes > 0) { lua_pushlstring(L, data, bytes); switch(EVP_PKEY_type(pkey->type)) { case EVP_PKEY_RSA: lua_pushstring(L, "RSA"); break; case EVP_PKEY_DSA: lua_pushstring(L, "DSA"); break; case EVP_PKEY_DH: lua_pushstring(L, "DH"); break; case EVP_PKEY_EC: lua_pushstring(L, "EC"); break; default: lua_pushstring(L, "Unknown"); break; } lua_pushinteger(L, EVP_PKEY_bits(pkey)); ret = 3; } else lua_pushnil(L); } else lua_pushnil(L); /* Cleanup */ BIO_free(bio); EVP_PKEY_free(pkey); return ret; }
static isc_result_t opensslgost_generate(dst_key_t *key, int unused, void (*callback)(int)) { EVP_PKEY_CTX *ctx; union { void *dptr; void (*fptr)(int); } u; EVP_PKEY *pkey = NULL; isc_result_t ret; UNUSED(unused); ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL); if (ctx == NULL) DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_new_id", DST_R_OPENSSLFAILURE)); if (callback != NULL) { u.fptr = callback; EVP_PKEY_CTX_set_app_data(ctx, u.dptr); EVP_PKEY_CTX_set_cb(ctx, &progress_cb); } if (EVP_PKEY_keygen_init(ctx) <= 0) DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen_init", DST_R_OPENSSLFAILURE)); if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_ctrl_str", DST_R_OPENSSLFAILURE)); if (EVP_PKEY_keygen(ctx, &pkey) <= 0) DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen", DST_R_OPENSSLFAILURE)); key->keydata.pkey = pkey; key->key_size = EVP_PKEY_bits(pkey); EVP_PKEY_CTX_free(ctx); return (ISC_R_SUCCESS); err: if (pkey != NULL) EVP_PKEY_free(pkey); if (ctx != NULL) EVP_PKEY_CTX_free(ctx); return (ret); }
static DH* SSLGetDHCallback(SSL* ssl, int exp, int keylen) { (void)exp; EVP_PKEY* pkey = SSL_get_privatekey(ssl); int type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE; // The keylen supplied by OpenSSL can only be 512 or 1024. // See ssl3_send_server_key_exchange() in ssl/s3_srvr.c if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) { keylen = EVP_PKEY_bits(pkey); } if (keylen >= 8192) { return g_dh_8192; } else if (keylen >= 4096) { return g_dh_4096; } else if (keylen >= 2048) { return g_dh_2048; } else { return g_dh_1024; } }
static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) { const EVP_MD *sigmd, *mgf1md; EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); int saltlen; if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0) return NULL; if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) return NULL; if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) return NULL; if (saltlen == -1) { saltlen = EVP_MD_size(sigmd); } else if (saltlen == -2) { saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; if ((EVP_PKEY_bits(pk) & 0x7) == 1) saltlen--; } return rsa_pss_params_create(sigmd, mgf1md, saltlen); }
int PKI_X509_KEYPAIR_VALUE_get_size ( PKI_X509_KEYPAIR_VALUE *pKey ) { int ret = -1; if (!pKey) { PKI_ERROR(PKI_ERR_PARAM_NULL, NULL); return ret; }; return EVP_PKEY_bits( pKey ); /* switch ( PKI_X509_KEYPAIR_VALUE_get_scheme( pKey ) ) { case PKI_SCHEME_DSA: case PKI_SCHEME_RSA: ret = EVP_PKEY_size ( pKey ); break; #ifdef ENABLE_ECDSA case PKI_SCHEME_ECDSA: if ((order = BN_new()) != NULL) { const EC_GROUP *group; if ((group = EC_KEY_get0_group(pKey->pkey.ec)) != NULL) { if (EC_GROUP_get_order(group, order, NULL)) { ret = BN_num_bits(order); }; }; if( order ) BN_free ( order ); }; break; }; #endif */ return ret; }
/* FIXME: Master-Key, Extensions, CA bits (openssl x509 -text -in servcert.pem) */ int _SSL_get_cert_info (struct cert_info *cert_info, SSL * ssl) { X509 *peer_cert; EVP_PKEY *peer_pkey; /* EVP_PKEY *ca_pkey; */ /* EVP_PKEY *tmp_pkey; */ char notBefore[64]; char notAfter[64]; int alg; int sign_alg; if (!(peer_cert = SSL_get_peer_certificate (ssl))) return (1); /* FATAL? */ X509_NAME_oneline (X509_get_subject_name (peer_cert), cert_info->subject, sizeof (cert_info->subject)); X509_NAME_oneline (X509_get_issuer_name (peer_cert), cert_info->issuer, sizeof (cert_info->issuer)); broke_oneline (cert_info->subject, cert_info->subject_word); broke_oneline (cert_info->issuer, cert_info->issuer_word); alg = OBJ_obj2nid (peer_cert->cert_info->key->algor->algorithm); sign_alg = OBJ_obj2nid (peer_cert->sig_alg->algorithm); ASN1_TIME_snprintf (notBefore, sizeof (notBefore), X509_get_notBefore (peer_cert)); ASN1_TIME_snprintf (notAfter, sizeof (notAfter), X509_get_notAfter (peer_cert)); peer_pkey = X509_get_pubkey (peer_cert); strncpy (cert_info->algorithm, (alg == NID_undef) ? "Unknown" : OBJ_nid2ln (alg), sizeof (cert_info->algorithm)); cert_info->algorithm_bits = EVP_PKEY_bits (peer_pkey); strncpy (cert_info->sign_algorithm, (sign_alg == NID_undef) ? "Unknown" : OBJ_nid2ln (sign_alg), sizeof (cert_info->sign_algorithm)); /* EVP_PKEY_bits(ca_pkey)); */ cert_info->sign_algorithm_bits = 0; strncpy (cert_info->notbefore, notBefore, sizeof (cert_info->notbefore)); strncpy (cert_info->notafter, notAfter, sizeof (cert_info->notafter)); EVP_PKEY_free (peer_pkey); /* SSL_SESSION_print_fp(stdout, SSL_get_session(ssl)); */ /* if (ssl->session->sess_cert->peer_rsa_tmp) { tmp_pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(tmp_pkey, ssl->session->sess_cert->peer_rsa_tmp); cert_info->rsa_tmp_bits = EVP_PKEY_bits (tmp_pkey); EVP_PKEY_free(tmp_pkey); } else fprintf(stderr, "REMOTE SIDE DOESN'T PROVIDES ->peer_rsa_tmp\n"); */ cert_info->rsa_tmp_bits = 0; X509_free (peer_cert); return (0); }
int main() { char dest_url[] = "https://www.hp.com"; BIO *certbio = NULL; BIO *outbio = NULL; X509 *cert = NULL; X509_NAME *certname = NULL; const SSL_METHOD *method; SSL_CTX *ctx; SSL *ssl; int server = 0; int ret, i; EVP_PKEY *pkey = NULL; /* ---------------------------------------------------------- * * These function calls initialize openssl for correct work. * * ---------------------------------------------------------- */ OpenSSL_add_all_algorithms(); ERR_load_BIO_strings(); ERR_load_crypto_strings(); SSL_load_error_strings(); /* ---------------------------------------------------------- * * Create the Input/Output BIO's. * * ---------------------------------------------------------- */ certbio = BIO_new(BIO_s_file()); outbio = BIO_new_fp(stdout, BIO_NOCLOSE); /* ---------------------------------------------------------- * * initialize SSL library and register algorithms * * ---------------------------------------------------------- */ if(SSL_library_init() < 0) BIO_printf(outbio, "Could not initialize the OpenSSL library !\n"); /* ---------------------------------------------------------- * * Set SSLv2 client hello, also announce SSLv3 and TLSv1 * * ---------------------------------------------------------- */ method = SSLv23_client_method(); /* ---------------------------------------------------------- * * Try to create a new SSL context * * ---------------------------------------------------------- */ if ( (ctx = SSL_CTX_new(method)) == NULL) BIO_printf(outbio, "Unable to create a new SSL context structure.\n"); /* ---------------------------------------------------------- * * Disabling SSLv2 will leave v3 and TSLv1 for negotiation * * ---------------------------------------------------------- */ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); /* ---------------------------------------------------------- * * Create new SSL connection state object * * ---------------------------------------------------------- */ ssl = SSL_new(ctx); /* ---------------------------------------------------------- * * Make the underlying TCP socket connection * * ---------------------------------------------------------- */ server = create_socket(dest_url, outbio); if(server != 0) BIO_printf(outbio, "Successfully made the TCP connection to: %s.\n", dest_url); /* ---------------------------------------------------------- * * Attach the SSL session to the socket descriptor * * ---------------------------------------------------------- */ SSL_set_fd(ssl, server); /* ---------------------------------------------------------- * * Try to SSL-connect here, returns 1 for success * * ---------------------------------------------------------- */ if ( SSL_connect(ssl) != 1 ) BIO_printf(outbio, "Error: Could not build a SSL session to: %s.\n", dest_url); else BIO_printf(outbio, "Successfully enabled SSL/TLS session to: %s.\n", dest_url); /* ---------------------------------------------------------- * * Get the remote certificate into the X509 structure * * ---------------------------------------------------------- */ cert = SSL_get_peer_certificate(ssl); if (cert == NULL) BIO_printf(outbio, "Error: Could not get a certificate from: %s.\n", dest_url); else BIO_printf(outbio, "Retrieved the server's certificate from: %s.\n", dest_url); if ((pkey = X509_get_pubkey(cert)) == NULL) BIO_printf(outbio, "Error getting public key from certificate"); if (pkey) { switch (pkey->type) { case EVP_PKEY_RSA: BIO_printf(outbio, "%d bit RSA Key\n\n", EVP_PKEY_bits(pkey)); break; case EVP_PKEY_DSA: BIO_printf(outbio, "%d bit DSA Key\n\n", EVP_PKEY_bits(pkey)); break; default: BIO_printf(outbio, "%d bit non-RSA/DSA Key\n\n", EVP_PKEY_bits(pkey)); break; } } if(!PEM_write_bio_PUBKEY(outbio, pkey)) BIO_printf(outbio, "Error writing public key data in PEM format"); /* ---------------------------------------------------------- * * extract various certificate information * * -----------------------------------------------------------*/ certname = X509_NAME_new(); certname = X509_get_subject_name(cert); /* ---------------------------------------------------------- * * display the cert subject here * * -----------------------------------------------------------*/ BIO_printf(outbio, "Displaying the certificate subject data:\n"); X509_NAME_print_ex(outbio, certname, 0, 0); BIO_printf(outbio, "\n"); /* ---------------------------------------------------------- * * Free the structures we don't need anymore * * -----------------------------------------------------------*/ SSL_free(ssl); close(server); X509_free(cert); SSL_CTX_free(ctx); BIO_printf(outbio, "Finished SSL/TLS connection with server: %s.\n", dest_url); return(0); }
static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig) { int pad_mode; EVP_PKEY_CTX *pkctx = ctx->pctx; if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) return 0; if (pad_mode == RSA_PKCS1_PADDING) return 2; if (pad_mode == RSA_PKCS1_PSS_PADDING) { const EVP_MD *sigmd, *mgf1md; RSA_PSS_PARAMS *pss = NULL; X509_ALGOR *mgf1alg = NULL; ASN1_STRING *os1 = NULL, *os2 = NULL; EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); int saltlen, rv = 0; sigmd = EVP_MD_CTX_md(ctx); if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) goto err; if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) goto err; if (saltlen == -1) saltlen = EVP_MD_size(sigmd); else if (saltlen == -2) { saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) saltlen--; } pss = RSA_PSS_PARAMS_new(); if (!pss) goto err; if (saltlen != 20) { pss->saltLength = ASN1_INTEGER_new(); if (!pss->saltLength) goto err; if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) goto err; } if (EVP_MD_type(sigmd) != NID_sha1) { pss->hashAlgorithm = X509_ALGOR_new(); if (!pss->hashAlgorithm) goto err; X509_ALGOR_set_md(pss->hashAlgorithm, sigmd); } if (EVP_MD_type(mgf1md) != NID_sha1) { ASN1_STRING *stmp = NULL; /* need to embed algorithm ID inside another */ mgf1alg = X509_ALGOR_new(); X509_ALGOR_set_md(mgf1alg, mgf1md); if (!ASN1_item_pack(mgf1alg, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) goto err; pss->maskGenAlgorithm = X509_ALGOR_new(); if (!pss->maskGenAlgorithm) goto err; X509_ALGOR_set0(pss->maskGenAlgorithm, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); } /* Finally create string with pss parameter encoding. */ if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os1)) goto err; if (alg2) { os2 = ASN1_STRING_dup(os1); if (!os2) goto err; X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os2); } X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os1); os1 = os2 = NULL; rv = 3; err: if (mgf1alg) X509_ALGOR_free(mgf1alg); if (pss) RSA_PSS_PARAMS_free(pss); if (os1) ASN1_STRING_free(os1); return rv; } return 2; }
int openssl_check_accept(openssl_con *c, struct redir_conn_t *conn) { #ifdef HAVE_OPENSSL int rc; if (!c || !c->con) return -1; if (!SSL_is_init_finished(c->con)) { if ((rc = SSL_accept(c->con)) <= 0) { int err = SSL_get_error(c->con, rc); switch (err) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: return 1; case SSL_ERROR_SYSCALL: if (errno != EINTR) { #if(_debug_ > 1) if (errno > 0) { syslog(LOG_DEBUG, "%s(%d): SSL handshake interrupted by system [Hint: Stop button pressed in browser?!]", __FUNCTION__, __LINE__); } else { syslog(LOG_DEBUG, "%s(%d): Spurious SSL handshake interrupt [Hint: Usually just one of those OpenSSL confusions!?]", __FUNCTION__, __LINE__); } #endif } break; } return -1; } else { #ifdef HAVE_OPENSSL_ENGINE X509 *peer_cert = SSL_get_peer_certificate(c->con); if (peer_cert) { char subj[1024]; X509_NAME_oneline(X509_get_subject_name(peer_cert),subj,sizeof(subj)); if (SSL_get_verify_result(c->con) != X509_V_OK) { syslog(LOG_DEBUG, "%s(%d): auth_failed: %s", __FUNCTION__, __LINE__, subj); X509_free(peer_cert); return -1; } syslog(LOG_DEBUG, "%s(%d): auth_success: %s", __FUNCTION__, __LINE__, subj); if (conn) conn->s_params.flags |= ADMIN_LOGIN; if (_options.debug) { EVP_PKEY *pktmp = X509_get_pubkey(peer_cert); #if OPENSSL_VERSION_NUMBER >= 0x10000000L const #endif SSL_CIPHER *cipher; char b[512]; syslog(LOG_DEBUG, "%s(%d): Debugging: SSL Information:\n", __FUNCTION__, __LINE__); cipher = SSL_get_current_cipher(c->con); syslog(LOG_DEBUG, "%s(%d): Protocol: %s, %s with %.*s bit key\n", __FUNCTION__, __LINE__, SSL_CIPHER_get_version(cipher), (char*)SSL_CIPHER_get_name(cipher), sprintf(b, "%d", EVP_PKEY_bits(pktmp)), b); syslog(LOG_DEBUG, "%s(%d): Subject: %s\n", __FUNCTION__, __LINE__, subj); X509_NAME_oneline(X509_get_issuer_name(peer_cert),b,sizeof(b)); syslog(LOG_DEBUG, "%s(%d): Issuer: %s\n", __FUNCTION__, __LINE__, b); EVP_PKEY_free(pktmp); } X509_free(peer_cert); } else { syslog(LOG_DEBUG, "%s(%d): no SSL certificate", __FUNCTION__, __LINE__); } #endif } } #elif HAVE_MATRIXSSL if (!c || !c->con) return -1; if (!SSL_is_init_finished(c->con)) { if (SSL_accept2(c->con) < 0) { return -1; } if (!SSL_is_init_finished(c->con)) return 1; } #endif return 0; }
static isc_result_t opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { dst_private_t priv; isc_result_t ret; int i; RSA *rsa = NULL, *pubrsa = NULL; #ifdef USE_ENGINE ENGINE *e = NULL; #endif isc_mem_t *mctx = key->mctx; const char *engine = NULL, *label = NULL; #if defined(USE_ENGINE) || USE_EVP EVP_PKEY *pkey = NULL; #endif #if USE_EVP if (pub != NULL && pub->keydata.pkey != NULL) pubrsa = EVP_PKEY_get1_RSA(pub->keydata.pkey); #else if (pub != NULL && pub->keydata.rsa != NULL) { pubrsa = pub->keydata.rsa; pub->keydata.rsa = NULL; } #endif /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); if (ret != ISC_R_SUCCESS) goto err; for (i = 0; i < priv.nelements; i++) { switch (priv.elements[i].tag) { case TAG_RSA_ENGINE: engine = (char *)priv.elements[i].data; break; case TAG_RSA_LABEL: label = (char *)priv.elements[i].data; break; default: break; } } /* * Is this key is stored in a HSM? * See if we can fetch it. */ if (label != NULL) { #ifdef USE_ENGINE if (engine == NULL) DST_RET(DST_R_NOENGINE); e = dst__openssl_getengine(engine); if (e == NULL) DST_RET(DST_R_NOENGINE); pkey = ENGINE_load_private_key(e, label, NULL, NULL); if (pkey == NULL) DST_RET(dst__openssl_toresult2( "ENGINE_load_private_key", ISC_R_NOTFOUND)); key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); key->label = isc_mem_strdup(key->mctx, label); if (key->label == NULL) DST_RET(ISC_R_NOMEMORY); rsa = EVP_PKEY_get1_RSA(pkey); if (rsa == NULL) DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); if (pubrsa != NULL) RSA_free(pubrsa); key->key_size = EVP_PKEY_bits(pkey); #if USE_EVP key->keydata.pkey = pkey; RSA_free(rsa); #else key->keydata.rsa = rsa; EVP_PKEY_free(pkey); #endif dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ISC_R_SUCCESS); #else DST_RET(DST_R_NOENGINE); #endif } rsa = RSA_new(); if (rsa == NULL) DST_RET(ISC_R_NOMEMORY); SET_FLAGS(rsa); #if USE_EVP pkey = EVP_PKEY_new(); if (pkey == NULL) DST_RET(ISC_R_NOMEMORY); if (!EVP_PKEY_set1_RSA(pkey, rsa)) DST_RET(ISC_R_FAILURE); key->keydata.pkey = pkey; #else key->keydata.rsa = rsa; #endif for (i = 0; i < priv.nelements; i++) { BIGNUM *bn; switch (priv.elements[i].tag) { case TAG_RSA_ENGINE: continue; case TAG_RSA_LABEL: continue; case TAG_RSA_PIN: continue; default: bn = BN_bin2bn(priv.elements[i].data, priv.elements[i].length, NULL); if (bn == NULL) DST_RET(ISC_R_NOMEMORY); } switch (priv.elements[i].tag) { case TAG_RSA_MODULUS: rsa->n = bn; break; case TAG_RSA_PUBLICEXPONENT: rsa->e = bn; break; case TAG_RSA_PRIVATEEXPONENT: rsa->d = bn; break; case TAG_RSA_PRIME1: rsa->p = bn; break; case TAG_RSA_PRIME2: rsa->q = bn; break; case TAG_RSA_EXPONENT1: rsa->dmp1 = bn; break; case TAG_RSA_EXPONENT2: rsa->dmq1 = bn; break; case TAG_RSA_COEFFICIENT: rsa->iqmp = bn; break; } } dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); key->key_size = BN_num_bits(rsa->n); if (pubrsa != NULL) RSA_free(pubrsa); #if USE_EVP RSA_free(rsa); #endif return (ISC_R_SUCCESS); err: #if USE_EVP if (pkey != NULL) EVP_PKEY_free(pkey); #endif if (rsa != NULL) RSA_free(rsa); if (pubrsa != NULL) RSA_free(pubrsa); opensslrsa_destroy(key); dst__privstruct_free(&priv, mctx); memset(&priv, 0, sizeof(priv)); return (ret); }
int mono_btls_key_get_bits (EVP_PKEY *pkey) { return EVP_PKEY_bits (pkey); }
static void print_stuff(BIO *bio, SSL *s, int full) { X509 *peer=NULL; char *p; static const char *space=" "; char buf[BUFSIZ]; STACK_OF(X509) *sk; STACK_OF(X509_NAME) *sk2; SSL_CIPHER *c; X509_NAME *xn; int j,i; #ifndef OPENSSL_NO_COMP const COMP_METHOD *comp, *expansion; #endif if (full) { int got_a_chain = 0; sk=SSL_get_peer_cert_chain(s); if (sk != NULL) { got_a_chain = 1; /* we don't have it for SSL2 (yet) */ BIO_printf(bio,"---\nCertificate chain\n"); for (i=0; i<sk_X509_num(sk); i++) { X509_NAME_oneline(X509_get_subject_name( sk_X509_value(sk,i)),buf,sizeof buf); BIO_printf(bio,"%2d s:%s\n",i,buf); X509_NAME_oneline(X509_get_issuer_name( sk_X509_value(sk,i)),buf,sizeof buf); BIO_printf(bio," i:%s\n",buf); if (c_showcerts) PEM_write_bio_X509(bio,sk_X509_value(sk,i)); } } BIO_printf(bio,"---\n"); peer=SSL_get_peer_certificate(s); if (peer != NULL) { BIO_printf(bio,"Server certificate\n"); if (!(c_showcerts && got_a_chain)) /* Redundant if we showed the whole chain */ PEM_write_bio_X509(bio,peer); X509_NAME_oneline(X509_get_subject_name(peer), buf,sizeof buf); BIO_printf(bio,"subject=%s\n",buf); X509_NAME_oneline(X509_get_issuer_name(peer), buf,sizeof buf); BIO_printf(bio,"issuer=%s\n",buf); } else BIO_printf(bio,"no peer certificate available\n"); sk2=SSL_get_client_CA_list(s); if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) { BIO_printf(bio,"---\nAcceptable client certificate CA names\n"); for (i=0; i<sk_X509_NAME_num(sk2); i++) { xn=sk_X509_NAME_value(sk2,i); X509_NAME_oneline(xn,buf,sizeof(buf)); BIO_write(bio,buf,strlen(buf)); BIO_write(bio,"\n",1); } } else { BIO_printf(bio,"---\nNo client certificate CA names sent\n"); } p=SSL_get_shared_ciphers(s,buf,sizeof buf); if (p != NULL) { /* This works only for SSL 2. In later protocol * versions, the client does not know what other * ciphers (in addition to the one to be used * in the current connection) the server supports. */ BIO_printf(bio,"---\nCiphers common between both SSL endpoints:\n"); j=i=0; while (*p) { if (*p == ':') { BIO_write(bio,space,15-j%25); i++; j=0; BIO_write(bio,((i%3)?" ":"\n"),1); } else { BIO_write(bio,p,1); j++; } p++; } BIO_write(bio,"\n",1); } BIO_printf(bio,"---\nSSL handshake has read %ld bytes and written %ld bytes\n", BIO_number_read(SSL_get_rbio(s)), BIO_number_written(SSL_get_wbio(s))); } BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, ")); c=SSL_get_current_cipher(s); BIO_printf(bio,"%s, Cipher is %s\n", SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c)); if (peer != NULL) { EVP_PKEY *pktmp; pktmp = X509_get_pubkey(peer); BIO_printf(bio,"Server public key is %d bit\n", EVP_PKEY_bits(pktmp)); EVP_PKEY_free(pktmp); } #ifndef OPENSSL_NO_COMP comp=SSL_get_current_compression(s); expansion=SSL_get_current_expansion(s); BIO_printf(bio,"Compression: %s\n", comp ? SSL_COMP_get_name(comp) : "NONE"); BIO_printf(bio,"Expansion: %s\n", expansion ? SSL_COMP_get_name(expansion) : "NONE"); #endif SSL_SESSION_print(bio,SSL_get_session(s)); BIO_printf(bio,"---\n"); if (peer != NULL) X509_free(peer); /* flush, or debugging output gets mixed with http response */ (void)BIO_flush(bio); }
static LUA_FUNCTION(openssl_pkey_parse) { EVP_PKEY *pkey = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); if (pkey->pkey.ptr) { lua_newtable(L); AUXILIAR_SET(L, -1, "bits", EVP_PKEY_bits(pkey), integer); AUXILIAR_SET(L, -1, "size", EVP_PKEY_size(pkey), integer); switch (EVP_PKEY_type(pkey->type)) { case EVP_PKEY_RSA: case EVP_PKEY_RSA2: { RSA* rsa = EVP_PKEY_get1_RSA(pkey); PUSH_OBJECT(rsa, "openssl.rsa"); lua_setfield(L, -2, "rsa"); AUXILIAR_SET(L, -1, "type", "rsa", string); } break; case EVP_PKEY_DSA: case EVP_PKEY_DSA2: case EVP_PKEY_DSA3: case EVP_PKEY_DSA4: { DSA* dsa = EVP_PKEY_get1_DSA(pkey); PUSH_OBJECT(dsa, "openssl.dsa"); lua_setfield(L, -2, "dsa"); AUXILIAR_SET(L, -1, "type", "dsa", string); } break; case EVP_PKEY_DH: { DH* dh = EVP_PKEY_get1_DH(pkey); PUSH_OBJECT(dh, "openssl.dh"); lua_rawseti(L, -2, 0); AUXILIAR_SET(L, -1, "type", "dh", string); } break; #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: { const EC_KEY* ec = EVP_PKEY_get1_EC_KEY(pkey); PUSH_OBJECT(ec, "openssl.ec_key"); lua_setfield(L, -2, "ec"); AUXILIAR_SET(L, -1, "type", "ec", string); } break; #endif default: break; }; return 1; } else luaL_argerror(L, 1, "not assign any keypair"); return 0; };
static isc_result_t opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label, const char *pin) { #ifdef USE_ENGINE ENGINE *e = NULL; isc_result_t ret; EVP_PKEY *pkey = NULL; RSA *rsa = NULL, *pubrsa = NULL; char *colon; UNUSED(pin); if (engine == NULL) DST_RET(DST_R_NOENGINE); e = dst__openssl_getengine(engine); if (e == NULL) DST_RET(DST_R_NOENGINE); pkey = ENGINE_load_public_key(e, label, NULL, NULL); if (pkey != NULL) { pubrsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); if (pubrsa == NULL) DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); } pkey = ENGINE_load_private_key(e, label, NULL, NULL); if (pkey == NULL) DST_RET(dst__openssl_toresult2("ENGINE_load_private_key", ISC_R_NOTFOUND)); if (engine != NULL) { key->engine = isc_mem_strdup(key->mctx, engine); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); } else { key->engine = isc_mem_strdup(key->mctx, label); if (key->engine == NULL) DST_RET(ISC_R_NOMEMORY); colon = strchr(key->engine, ':'); if (colon != NULL) *colon = '\0'; } key->label = isc_mem_strdup(key->mctx, label); if (key->label == NULL) DST_RET(ISC_R_NOMEMORY); rsa = EVP_PKEY_get1_RSA(pkey); if (rsa == NULL) DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) DST_RET(DST_R_INVALIDPRIVATEKEY); if (pubrsa != NULL) RSA_free(pubrsa); key->key_size = EVP_PKEY_bits(pkey); #if USE_EVP key->keydata.pkey = pkey; RSA_free(rsa); #else key->keydata.rsa = rsa; EVP_PKEY_free(pkey); #endif return (ISC_R_SUCCESS); err: if (rsa != NULL) RSA_free(rsa); if (pubrsa != NULL) RSA_free(pubrsa); if (pkey != NULL) EVP_PKEY_free(pkey); return (ret); #else UNUSED(key); UNUSED(engine); UNUSED(label); UNUSED(pin); return(DST_R_NOENGINE); #endif }