static VALUE ec_instance(VALUE klass, EC_KEY *ec) { EVP_PKEY *pkey; VALUE obj; if (!ec) { return Qfalse; } if (!(pkey = EVP_PKEY_new())) { return Qfalse; } if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { EVP_PKEY_free(pkey); return Qfalse; } WrapPKey(klass, obj, pkey); return obj; }
/*! * \brief Create ECDSA private key from key parameters. * \see rsa_create_pkey */ static int ecdsa_create_pkey(const knot_key_params_t *params, EVP_PKEY *key) { assert(params); assert(key); int curve; if (params->algorithm == KNOT_DNSSEC_ALG_ECDSAP256SHA256) { curve = NID_X9_62_prime256v1; // == secp256r1 } else if (params->algorithm == KNOT_DNSSEC_ALG_ECDSAP384SHA384) { curve = NID_secp384r1; } else { return KNOT_DNSSEC_ENOTSUP; } EC_KEY *ec_key = EC_KEY_new_by_curve_name(curve); if (ec_key == NULL) { return KNOT_ENOMEM; } int result = ecdsa_set_public_key(¶ms->rdata, ec_key); if (result != KNOT_EOK) { EC_KEY_free(ec_key); return result; } result = ecdsa_set_private_key(¶ms->private_key, ec_key); if (result != KNOT_EOK) { EC_KEY_free(ec_key); return result; } if (EC_KEY_check_key(ec_key) != 1) { EC_KEY_free(ec_key); return KNOT_DNSSEC_EINVALID_KEY; } if (!EVP_PKEY_assign_EC_KEY(key, ec_key)) { EC_KEY_free(ec_key); return KNOT_DNSSEC_EASSIGN_KEY; } return KNOT_EOK; }
static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { EC_KEY *ec = NULL; EC_PKEY_CTX *dctx = ctx->data; int ret = 0; if (dctx->gen_group == NULL) { ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET); return 0; } ec = EC_KEY_new(); if (ec == NULL) return 0; ret = EC_KEY_set_group(ec, dctx->gen_group); if (ret) EVP_PKEY_assign_EC_KEY(pkey, ec); else EC_KEY_free(ec); return ret; }
void ECDSAKeyPair::generateKey(EC_GROUP * group) throw (AsymmetricKeyException) { EC_KEY* eckey = EC_KEY_new(); if (eckey == NULL){ throw AsymmetricKeyException(AsymmetricKeyException::INTERNAL_ERROR, "Failed initiate EC_KEY", "ECDSAKeyPair::generateKey"); } //assert (need_rand);?? if (EC_KEY_set_group(eckey, group) == 0){ EC_KEY_free(eckey); EC_GROUP_free(group); throw AsymmetricKeyException(AsymmetricKeyException::INTERNAL_ERROR, "Failed to set group", "ECDSAKeyPair::generateKey"); } if (!EC_KEY_generate_key(eckey)) { EC_KEY_free(eckey); EC_GROUP_free(group); throw AsymmetricKeyException(AsymmetricKeyException::INTERNAL_ERROR, "Failed to generate keys", "ECDSAKeyPair::generateKey"); } if (!eckey) { EC_KEY_free(eckey); EC_GROUP_free(group); throw AsymmetricKeyException(AsymmetricKeyException::INTERNAL_ERROR, "Failed to generate keys", "ECDSAKeyPair::generateKey"); } this->key = EVP_PKEY_new(); EVP_PKEY_assign_EC_KEY(this->key, eckey); if (!this->key) { EC_KEY_free(eckey); EC_GROUP_free(group); throw AsymmetricKeyException(AsymmetricKeyException::INTERNAL_ERROR, "Failed to assert EC_KEY into EVP_KEY", "ECDSAKeyPair::generateKey"); } }
static int eckey_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { // See RFC 5915. EC_GROUP *group = EC_KEY_parse_parameters(params); if (group == NULL || CBS_len(params) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); EC_GROUP_free(group); return 0; } EC_KEY *ec_key = EC_KEY_parse_private_key(key, group); EC_GROUP_free(group); if (ec_key == NULL || CBS_len(key) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); EC_KEY_free(ec_key); return 0; } EVP_PKEY_assign_EC_KEY(out, ec_key); return 1; }
ECDSAKeyPair::ECDSAKeyPair(AsymmetricKey::Curve curve, bool named) throw (AsymmetricKeyException) { EC_KEY *eckey; this->key = NULL; this->engine = NULL; eckey = NULL; eckey = EC_KEY_new_by_curve_name(curve); if (named) EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE); EC_KEY_generate_key(eckey); if (!eckey) { throw AsymmetricKeyException(AsymmetricKeyException::INTERNAL_ERROR, "ECDSAKeyPair::ECDSAKeyPair"); } this->key = EVP_PKEY_new(); EVP_PKEY_assign_EC_KEY(this->key, eckey); if (!this->key) { throw AsymmetricKeyException(AsymmetricKeyException::INTERNAL_ERROR, "ECDSAKeyPair::ECDSAKeyPair"); } }
static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { EC_KEY *ec = NULL; EC_PKEY_CTX *dctx = ctx->data; int ret = 0; if (dctx->gen_group == NULL) { OPENSSL_PUT_ERROR(EVP, pkey_ec_paramgen, EVP_R_NO_PARAMETERS_SET); return 0; } ec = EC_KEY_new(); if (!ec) { return 0; } ret = EC_KEY_set_group(ec, dctx->gen_group); if (ret) { EVP_PKEY_assign_EC_KEY(pkey, ec); } else { EC_KEY_free(ec); } return ret; }
EVP_PKEY* sldns_ecdsa2pkey_raw(unsigned char* key, size_t keylen, uint8_t algo) { unsigned char buf[256+2]; /* sufficient for 2*384/8+1 */ const unsigned char* pp = buf; EVP_PKEY *evp_key; EC_KEY *ec; /* check length, which uncompressed must be 2 bignums */ if(algo == LDNS_ECDSAP256SHA256) { if(keylen != 2*256/8) return NULL; ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); } else if(algo == LDNS_ECDSAP384SHA384) { if(keylen != 2*384/8) return NULL; ec = EC_KEY_new_by_curve_name(NID_secp384r1); } else ec = NULL; if(!ec) return NULL; if(keylen+1 > sizeof(buf)) { /* sanity check */ EC_KEY_free(ec); return NULL; } /* prepend the 0x02 (from docs) (or actually 0x04 from implementation * of openssl) for uncompressed data */ buf[0] = POINT_CONVERSION_UNCOMPRESSED; memmove(buf+1, key, keylen); if(!o2i_ECPublicKey(&ec, &pp, (int)keylen+1)) { EC_KEY_free(ec); return NULL; } evp_key = EVP_PKEY_new(); if(!evp_key) { EC_KEY_free(ec); return NULL; } if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) { EVP_PKEY_free(evp_key); EC_KEY_free(ec); return NULL; } return evp_key; }
static EVP_PKEY *old_priv_decode(CBS *cbs, int type) { EVP_PKEY *ret = EVP_PKEY_new(); if (ret == NULL) { return NULL; } switch (type) { case EVP_PKEY_EC: { EC_KEY *ec_key = EC_KEY_parse_private_key(cbs, NULL); if (ec_key == NULL || !EVP_PKEY_assign_EC_KEY(ret, ec_key)) { EC_KEY_free(ec_key); goto err; } return ret; } case EVP_PKEY_DSA: { DSA *dsa = DSA_parse_private_key(cbs); if (dsa == NULL || !EVP_PKEY_assign_DSA(ret, dsa)) { DSA_free(dsa); goto err; } return ret; } case EVP_PKEY_RSA: { RSA *rsa = RSA_parse_private_key(cbs); if (rsa == NULL || !EVP_PKEY_assign_RSA(ret, rsa)) { RSA_free(rsa); goto err; } return ret; } default: OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE); goto err; } err: EVP_PKEY_free(ret); return NULL; }
static VALUE ossl_ec_key_initialize_copy(VALUE self, VALUE other) { EVP_PKEY *pkey; EC_KEY *ec, *ec_new; GetPKey(self, pkey); if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) ossl_raise(eECError, "EC already initialized"); SafeRequire_EC_KEY(other, ec); ec_new = EC_KEY_dup(ec); if (!ec_new) ossl_raise(eECError, "EC_KEY_dup"); if (!EVP_PKEY_assign_EC_KEY(pkey, ec_new)) { EC_KEY_free(ec_new); ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); } rb_iv_set(self, "@group", Qnil); /* EC_KEY_dup() also copies the EC_GROUP */ return self; }
static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { EC_KEY *ec = NULL; EC_PKEY_CTX *dctx = ctx->data; if (ctx->pkey == NULL && dctx->gen_group == NULL) { ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET); return 0; } ec = EC_KEY_new(); if (!ec) return 0; EVP_PKEY_assign_EC_KEY(pkey, ec); if (ctx->pkey) { /* Note: if error return, pkey is freed by parent routine */ if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) return 0; } else { if (!EC_KEY_set_group(ec, dctx->gen_group)) return 0; } return EC_KEY_generate_key(pkey->pkey.ec); }
static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { const uint8_t *p = NULL; void *pval; int ptype, pklen; EC_KEY *eckey = NULL; X509_ALGOR *palg; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) { return 0; } X509_ALGOR_get0(NULL, &ptype, &pval, palg); if (ptype != V_ASN1_OBJECT) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); return 0; } eckey = EC_KEY_new_by_curve_name(OBJ_obj2nid((ASN1_OBJECT *)pval)); if (eckey == NULL) { OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); return 0; } /* We have parameters now set public key */ if (!o2i_ECPublicKey(&eckey, &p, pklen)) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); goto err; } EVP_PKEY_assign_EC_KEY(pkey, eckey); return 1; err: if (eckey) { EC_KEY_free(eckey); } return 0; }
static EP_STAT generate_ec_key(EP_CRYPTO_KEY *key, const char *curve) { if (curve == NULL) curve = ep_adm_getstrparam("libep.crypto.key.ec.curve", "sect283r1"); int nid = OBJ_txt2nid(curve); if (nid == NID_undef) { _ep_crypto_error("unknown EC curve name %s", curve); goto fail0; } EC_KEY *eckey = EC_KEY_new_by_curve_name(nid); if (eckey == NULL) { _ep_crypto_error("cannot create EC key"); goto fail0; } if (!EC_KEY_generate_key(eckey)) { _ep_crypto_error("cannot generate EC key"); goto fail1; } if (EVP_PKEY_assign_EC_KEY(key, eckey) != 1) { _ep_crypto_error("cannot assign EC key"); goto fail1; } return EP_STAT_OK; fail1: EC_KEY_free(eckey); fail0: return EP_STAT_CRYPTO_KEYCREATE; }
PKI_X509_KEYPAIR *HSM_PKCS11_KEYPAIR_new( PKI_KEYPARAMS *kp, URL *url, PKI_CRED *cred, HSM *driver ) { PKCS11_HANDLER *lib = NULL; int type = PKI_SCHEME_DEFAULT; /* CK_MECHANISM DSA_MECH = { CKM_DSA_KEY_PAIR_GEN, NULL_PTR, 0 }; CK_MECHANISM ECDSA_MECH = { CKM_ECDSA_KEY_PAIR_GEN, NULL_PTR, 0 }; */ /* Return EVP Key */ PKI_X509_KEYPAIR *ret = NULL; PKI_X509_KEYPAIR_VALUE *val = NULL; /* If a RSA Key is generated we use the RSA pointer*/ PKI_RSA_KEY *rsa = NULL; /* If a DSA Key is generated we use the DSA pointer*/ PKI_DSA_KEY *dsa = NULL; #ifdef ENABLE_ECDSA /* If an ECDSA Key is generated we use the DSA pointer*/ PKI_EC_KEY *ecdsa = NULL; #endif PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Start!"); if ((lib = _hsm_get_pkcs11_handler ( driver )) == NULL ) { PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Can not get handler"); return NULL; } /* if((val = (PKI_X509_KEYPAIR *) EVP_PKEY_new()) == NULL ) { return NULL; } */ /* if( _pki_pkcs11_rand_seed() == 0 ) { PKI_log_debug("WARNING, low rand available!"); } */ if ( kp && kp->scheme != PKI_SCHEME_UNKNOWN ) type = kp->scheme; switch (type) { case PKI_SCHEME_RSA: break; case PKI_SCHEME_DSA: case PKI_SCHEME_ECDSA: default: PKI_ERROR(PKI_ERR_HSM_SCHEME_UNSUPPORTED, "Scheme %d", type ); return ( NULL ); } /* PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Closing existing key session"); rv = lib->callbacks->C_CloseSession( lib->session ); */ if(( HSM_PKCS11_session_new( lib->slot_id, &lib->session, CKF_SERIAL_SESSION | CKF_RW_SESSION, lib )) == PKI_ERR ) { PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Failed in opening a " "new session (R/W) with the token" ); return ( NULL ); }; /* PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Opening new R/W key session"); if((rv = lib->callbacks->C_OpenSession (lib->slot_id, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &(lib->session))) != CKR_OK ) { PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Failed in opening a " "new session (R/W) with the token" ); return ( NULL ); } */ if( HSM_PKCS11_login ( driver, cred ) == PKI_ERR ) { HSM_PKCS11_session_close ( &lib->session, lib ); return ( PKI_ERR ); } /* PKI_log_debug("HSM_PKCS11_KEYPAIR_new()::Logging in" ); rv = lib->callbacks->C_Login(lib->session, CKU_USER, (CK_UTF8CHAR *) cred->password, cred->password ? strlen(cred->password) : 0); */ /* if ( rv == CKR_USER_ALREADY_LOGGED_IN ) { PKI_log_debug( "HSM_PKCS11_SLOT_select()::User Already logged " "in!"); } else if( rv == CKR_PIN_INCORRECT ) { PKI_log_err ( "HSM_PKCS11_SLOT_select()::Can not login " "- Pin Incorrect (0X%8.8X) [%s]", rv, cred->password); return ( PKI_ERR ); } else if ( rv != CKR_OK ) { PKI_log_err ( "HSM_PKCS11_SLOT_select()::Can not login " "- General Error (0X%8.8X)", rv); return ( PKI_ERR ); } */ /* Generate the EVP_PKEY that will allow it to make use of it */ if((val = (PKI_X509_KEYPAIR_VALUE *) EVP_PKEY_new()) == NULL ) { HSM_PKCS11_session_close ( &lib->session, lib ); PKI_ERROR(PKI_ERR_OBJECT_CREATE, "KeyPair value"); return NULL; } switch( type ) { case PKI_SCHEME_RSA: if ((rsa = _pki_pkcs11_rsakey_new ( kp, url, lib, driver)) == NULL ) { HSM_PKCS11_session_close ( &lib->session, lib ); return ( NULL ); }; if(!EVP_PKEY_assign_RSA( (EVP_PKEY *) val, rsa)) { PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign RSA key"); if( rsa ) RSA_free ( rsa ); if( val ) EVP_PKEY_free( (EVP_PKEY *) val ); HSM_PKCS11_session_close ( &lib->session, lib ); return ( NULL ); } break; case PKI_SCHEME_DSA: if ((dsa = _pki_pkcs11_dsakey_new ( kp, url, lib, driver)) == NULL ) { HSM_PKCS11_session_close ( &lib->session, lib ); return ( NULL ); }; if(!EVP_PKEY_assign_DSA( (EVP_PKEY *) val, dsa)) { PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign DSA key"); if( dsa ) DSA_free ( dsa ); if( val ) EVP_PKEY_free( (EVP_PKEY *) val ); HSM_PKCS11_session_close ( &lib->session, lib ); return ( NULL ); } break; #ifdef ENABLE_ECDSA case PKI_SCHEME_ECDSA: if ((ecdsa = _pki_pkcs11_ecdsakey_new ( kp, url, lib, driver)) == NULL ) { HSM_PKCS11_session_close ( &lib->session, lib ); return ( NULL ); }; if(!EVP_PKEY_assign_EC_KEY( (EVP_PKEY *) val, ecdsa)) { PKI_ERROR(PKI_ERR_X509_KEYPAIR_GENERATION, "Can not assign ECDSA key"); if( ecdsa ) EC_KEY_free ( ecdsa ); if( val ) EVP_PKEY_free( (EVP_PKEY *) val ); HSM_PKCS11_session_close ( &lib->session, lib ); return ( NULL ); } break; #endif default: PKI_ERROR(PKI_ERR_HSM_SCHEME_UNSUPPORTED, "%d", type); if ( val ) EVP_PKEY_free ( (EVP_PKEY *) val ); HSM_PKCS11_session_close ( &lib->session, lib ); return ( NULL ); } HSM_PKCS11_session_close ( &lib->session, lib ); if (( ret = PKI_X509_new ( PKI_DATATYPE_X509_KEYPAIR, driver)) == NULL){ PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL ); if ( val ) EVP_PKEY_free ( (EVP_PKEY *) val ); if ( val ) EVP_PKEY_free ( val ); return NULL; } ret->value = val; /* Let's return the PKI_X509_KEYPAIR infrastructure */ return ( ret ); }
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) { EVP_PKEY *pkey = NULL; #ifndef OPENSSL_NO_RSA RSA *rsa = NULL; #endif #ifndef OPENSSL_NO_DSA DSA *dsa = NULL; ASN1_TYPE *t1, *t2; ASN1_INTEGER *privkey; STACK_OF(ASN1_TYPE) *ndsa = NULL; #endif #ifndef OPENSSL_NO_EC EC_KEY *eckey = NULL; const unsigned char *p_tmp; #endif #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) ASN1_TYPE *param = NULL; BN_CTX *ctx = NULL; int plen; #endif X509_ALGOR *a; const unsigned char *p; const unsigned char *cp; int pkeylen; int nid; char obj_tmp[80]; if(p8->pkey->type == V_ASN1_OCTET_STRING) { p8->broken = PKCS8_OK; p = p8->pkey->value.octet_string->data; pkeylen = p8->pkey->value.octet_string->length; } else { p8->broken = PKCS8_NO_OCTET; p = p8->pkey->value.sequence->data; pkeylen = p8->pkey->value.sequence->length; } if (!(pkey = EVP_PKEY_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); return NULL; } a = p8->pkeyalg; nid = OBJ_obj2nid(a->algorithm); switch(nid) { #ifndef OPENSSL_NO_RSA case NID_rsaEncryption: cp = p; if (!(rsa = d2i_RSAPrivateKey (NULL,&cp, pkeylen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); return NULL; } EVP_PKEY_assign_RSA (pkey, rsa); break; #endif #ifndef OPENSSL_NO_DSA case NID_dsa: /* PKCS#8 DSA is weird: you just get a private key integer * and parameters in the AlgorithmIdentifier the pubkey must * be recalculated. */ /* Check for broken DSA PKCS#8, UGH! */ if(*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED)) { if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pkeylen, d2i_ASN1_TYPE, ASN1_TYPE_free))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } if(sk_ASN1_TYPE_num(ndsa) != 2 ) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } /* Handle Two broken types: * SEQUENCE {parameters, priv_key} * SEQUENCE {pub_key, priv_key} */ t1 = sk_ASN1_TYPE_value(ndsa, 0); t2 = sk_ASN1_TYPE_value(ndsa, 1); if(t1->type == V_ASN1_SEQUENCE) { p8->broken = PKCS8_EMBEDDED_PARAM; param = t1; } else if(a->parameter->type == V_ASN1_SEQUENCE) { p8->broken = PKCS8_NS_DB; param = a->parameter; } else { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } if(t2->type != V_ASN1_INTEGER) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } privkey = t2->value.integer; } else { if (!(privkey=d2i_ASN1_INTEGER (NULL, &p, pkeylen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } param = p8->pkeyalg->parameter; } if (!param || (param->type != V_ASN1_SEQUENCE)) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } cp = p = param->value.sequence->data; plen = param->value.sequence->length; if (!(dsa = d2i_DSAparams (NULL, &cp, plen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto dsaerr; } /* We have parameters now set private key */ if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_DECODE_ERROR); goto dsaerr; } /* Calculate public key (ouch!) */ if (!(dsa->pub_key = BN_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!(ctx = BN_CTX_new())) { EVPerr(EVP_F_EVP_PKCS82PKEY,ERR_R_MALLOC_FAILURE); goto dsaerr; } if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { EVPerr(EVP_F_EVP_PKCS82PKEY,EVP_R_BN_PUBKEY_ERROR); goto dsaerr; } EVP_PKEY_assign_DSA(pkey, dsa); BN_CTX_free (ctx); if(ndsa) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); else ASN1_INTEGER_free(privkey); break; dsaerr: BN_CTX_free (ctx); sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); DSA_free(dsa); EVP_PKEY_free(pkey); return NULL; break; #endif #ifndef OPENSSL_NO_EC case NID_X9_62_id_ecPublicKey: p_tmp = p; /* extract the ec parameters */ param = p8->pkeyalg->parameter; if (!param || ((param->type != V_ASN1_SEQUENCE) && (param->type != V_ASN1_OBJECT))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto ecerr; } if (param->type == V_ASN1_SEQUENCE) { cp = p = param->value.sequence->data; plen = param->value.sequence->length; if (!(eckey = d2i_ECParameters(NULL, &cp, plen))) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto ecerr; } } else { EC_GROUP *group; cp = p = param->value.object->data; plen = param->value.object->length; /* type == V_ASN1_OBJECT => the parameters are given * by an asn1 OID */ if ((eckey = EC_KEY_new()) == NULL) { EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE); goto ecerr; } group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object)); if (group == NULL) goto ecerr; EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); if (EC_KEY_set_group(eckey, group) == 0) goto ecerr; EC_GROUP_free(group); } /* We have parameters now set private key */ if (!d2i_ECPrivateKey(&eckey, &p_tmp, pkeylen)) { EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_DECODE_ERROR); goto ecerr; } /* calculate public key (if necessary) */ if (EC_KEY_get0_public_key(eckey) == NULL) { const BIGNUM *priv_key; const EC_GROUP *group; EC_POINT *pub_key; /* the public key was not included in the SEC1 private * key => calculate the public key */ group = EC_KEY_get0_group(eckey); pub_key = EC_POINT_new(group); if (pub_key == NULL) { EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { EC_POINT_free(pub_key); EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } priv_key = EC_KEY_get0_private_key(eckey); if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) { EC_POINT_free(pub_key); EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } if (EC_KEY_set_public_key(eckey, pub_key) == 0) { EC_POINT_free(pub_key); EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB); goto ecerr; } EC_POINT_free(pub_key); } EVP_PKEY_assign_EC_KEY(pkey, eckey); if (ctx) BN_CTX_free(ctx); break; ecerr: if (ctx) BN_CTX_free(ctx); if (eckey) EC_KEY_free(eckey); if (pkey) EVP_PKEY_free(pkey); return NULL; #endif default: EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); if (!a->algorithm) BUF_strlcpy (obj_tmp, "NULL", sizeof obj_tmp); else i2t_ASN1_OBJECT(obj_tmp, 80, a->algorithm); ERR_add_error_data(2, "TYPE=", obj_tmp); EVP_PKEY_free (pkey); return NULL; } return pkey; }
static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { const unsigned char *p = NULL; void *pval; int ptype, pklen; EC_KEY *eckey = NULL; X509_ALGOR *palg; if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) return 0; X509_ALGOR_get0(NULL, &ptype, &pval, palg); eckey = eckey_type2param(ptype, pval); if (!eckey) goto ecliberr; /* We have parameters now set private key */ if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); goto ecerr; } /* calculate public key (if necessary) */ if (EC_KEY_get0_public_key(eckey) == NULL) { const BIGNUM *priv_key; const EC_GROUP *group; EC_POINT *pub_key; /* the public key was not included in the SEC1 private * key => calculate the public key */ group = EC_KEY_get0_group(eckey); pub_key = EC_POINT_new(group); if (pub_key == NULL) { ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); goto ecliberr; } if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { EC_POINT_free(pub_key); ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); goto ecliberr; } priv_key = EC_KEY_get0_private_key(eckey); if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { EC_POINT_free(pub_key); ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); goto ecliberr; } if (EC_KEY_set_public_key(eckey, pub_key) == 0) { EC_POINT_free(pub_key); ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); goto ecliberr; } EC_POINT_free(pub_key); } EVP_PKEY_assign_EC_KEY(pkey, eckey); return 1; ecliberr: ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); ecerr: if (eckey) EC_KEY_free(eckey); return 0; }
EVP_PKEY *CPK_MASTER_SECRET_extract_private_key( CPK_MASTER_SECRET *master, const char *id) { EVP_PKEY *pkey = NULL; int pkey_type; if (!(pkey = EVP_PKEY_new())) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_MALLOC_FAILURE); goto err; } pkey_type = OBJ_obj2nid(master->pkey_algor->algorithm); if (pkey_type == EVP_PKEY_DSA) { DSA *dsa; if (!(dsa = extract_dsa_priv_key(master, id))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_CPK_LIB); goto err; } if (!EVP_PKEY_assign_DSA(pkey, dsa)) { DSA_free(dsa); CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_EVP_LIB); goto err; } } else if (pkey_type == EVP_PKEY_EC) { EC_KEY *ec_key; if (!(ec_key = extract_ec_priv_key(master, id))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_CPK_LIB); goto err; } if (!EVP_PKEY_assign_EC_KEY(pkey, ec_key)) { EC_KEY_free(ec_key); CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_EVP_LIB); goto err; } } else { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, CPK_R_INVALID_PKEY_TYPE); goto err; } /* * add id to EVP_PKEY attributes */ /* if(!X509_NAME_get_text_by_NID(master->id, NID_organizationName, domain_id, sizeof(domain_id))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_X509_LIB); goto err; } if (!EVP_PKEY_add1_attr_by_NID(pkey, NID_organizationName, V_ASN1_PRINTABLESTRING, (const unsigned char *)domain_id, strlen(domain_id))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_EVP_LIB); goto err; } if (!EVP_PKEY_add1_attr_by_NID(pkey, NID_commonName, V_ASN1_PRINTABLESTRING, (const unsigned char *)id, strlen(id))) { CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY, ERR_R_EVP_LIB); goto err; } */ return pkey; err: if (pkey) EVP_PKEY_free(pkey); return NULL; }
/* call-seq: * OpenSSL::PKey::EC.new() * OpenSSL::PKey::EC.new(ec_key) * OpenSSL::PKey::EC.new(ec_group) * OpenSSL::PKey::EC.new("secp112r1") * OpenSSL::PKey::EC.new(pem_string) * OpenSSL::PKey::EC.new(pem_string [, pwd]) * OpenSSL::PKey::EC.new(der_string) * * See the OpenSSL documentation for: * EC_KEY_* */ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; EC_KEY *ec = NULL; VALUE arg, pass; VALUE group = Qnil; char *passwd = NULL; GetPKey(self, pkey); if (pkey->pkey.ec) rb_raise(eECError, "EC_KEY already initialized"); rb_scan_args(argc, argv, "02", &arg, &pass); if (NIL_P(arg)) { ec = EC_KEY_new(); } else { if (rb_obj_is_kind_of(arg, cEC)) { EC_KEY *other_ec = NULL; SafeRequire_EC_KEY(arg, other_ec); ec = EC_KEY_dup(other_ec); } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { ec = EC_KEY_new(); group = arg; } else { BIO *in = ossl_obj2bio(arg); if (!NIL_P(pass)) { passwd = StringValuePtr(pass); } ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd); if (!ec) { (void)BIO_reset(in); (void)ERR_get_error(); ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, passwd); } if (!ec) { (void)BIO_reset(in); (void)ERR_get_error(); ec = d2i_ECPrivateKey_bio(in, NULL); } if (!ec) { (void)BIO_reset(in); (void)ERR_get_error(); ec = d2i_EC_PUBKEY_bio(in, NULL); } BIO_free(in); if (ec == NULL) { const char *name = StringValueCStr(arg); int nid = OBJ_sn2nid(name); (void)ERR_get_error(); if (nid == NID_undef) ossl_raise(eECError, "unknown curve name (%s)\n", name); if ((ec = EC_KEY_new_by_curve_name(nid)) == NULL) ossl_raise(eECError, "unable to create curve (%s)\n", name); EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE); EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); } } } if (ec == NULL) ossl_raise(eECError, NULL); if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { EC_KEY_free(ec); ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); } rb_iv_set(self, "@group", Qnil); if (!NIL_P(group)) rb_funcall(self, rb_intern("group="), 1, arg); return self; }
/* * verify EC signature on JWT */ static apr_byte_t apr_jws_verify_ec(apr_pool_t *pool, apr_jwt_t *jwt, apr_jwk_t *jwk, apr_jwt_error_t *err) { int nid = apr_jws_ec_alg_to_curve(jwt->header.alg); if (nid == -1) { apr_jwt_error(err, "no OpenSSL Elliptic Curve identifier found for algorithm \"%s\"", jwt->header.alg); return FALSE; } EC_GROUP *curve = EC_GROUP_new_by_curve_name(nid); if (curve == NULL) { apr_jwt_error(err, "no OpenSSL Elliptic Curve found for algorithm \"%s\"", jwt->header.alg); return FALSE; } apr_byte_t rc = FALSE; /* get the OpenSSL digest function */ const EVP_MD *digest = NULL; if ((digest = apr_jws_crypto_alg_to_evp(pool, jwt->header.alg, err)) == NULL) return FALSE; EVP_MD_CTX ctx; EVP_MD_CTX_init(&ctx); EC_KEY * pubkey = EC_KEY_new(); EC_KEY_set_group(pubkey, curve); BIGNUM * x = BN_new(); BIGNUM * y = BN_new(); BN_bin2bn(jwk->key.ec->x, jwk->key.ec->x_len, x); BN_bin2bn(jwk->key.ec->y, jwk->key.ec->y_len, y); if (!EC_KEY_set_public_key_affine_coordinates(pubkey, x, y)) { apr_jwt_error_openssl(err, "EC_KEY_set_public_key_affine_coordinates"); return FALSE; } EVP_PKEY* pEcKey = EVP_PKEY_new(); if (!EVP_PKEY_assign_EC_KEY(pEcKey, pubkey)) { pEcKey = NULL; apr_jwt_error_openssl(err, "EVP_PKEY_assign_EC_KEY"); goto end; } ctx.pctx = EVP_PKEY_CTX_new(pEcKey, NULL); if (!EVP_PKEY_verify_init(ctx.pctx)) { apr_jwt_error_openssl(err, "EVP_PKEY_verify_init"); goto end; } if (!EVP_VerifyInit_ex(&ctx, digest, NULL)) { apr_jwt_error_openssl(err, "EVP_VerifyInit_ex"); goto end; } if (!EVP_VerifyUpdate(&ctx, jwt->message, strlen(jwt->message))) { apr_jwt_error_openssl(err, "EVP_VerifyUpdate"); goto end; } if (!EVP_VerifyFinal(&ctx, (const unsigned char *) jwt->signature.bytes, jwt->signature.length, pEcKey)) { apr_jwt_error_openssl(err, "wrong key? EVP_VerifyFinal"); goto end; } rc = TRUE; end: if (pEcKey) { EVP_PKEY_free(pEcKey); } else if (pubkey) { EC_KEY_free(pubkey); } EVP_MD_CTX_cleanup(&ctx); return rc; }
EVP_PKEY *CPK_PUBLIC_PARAMS_extract_public_key(CPK_PUBLIC_PARAMS *param, const char *id) { EVP_PKEY *pkey = NULL; int pkey_type; //char domain_id[CPK_MAX_ID_LENGTH + 1]; if (!(pkey = EVP_PKEY_new())) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_MALLOC_FAILURE); goto err; } pkey_type = OBJ_obj2nid(param->pkey_algor->algorithm); if (pkey_type == EVP_PKEY_DSA) { DSA *dsa = NULL; if (!(dsa = extract_dsa_pub_key(param, id))) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_CPK_LIB); goto err; } if (!EVP_PKEY_assign_DSA(pkey, dsa)) { DSA_free(dsa); CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_EVP_LIB); goto err; } } else if (pkey_type == EVP_PKEY_EC) { EC_KEY *ec_key = NULL; if (!(ec_key = extract_ec_pub_key(param, id))) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_CPK_LIB); goto err; } if (!EVP_PKEY_assign_EC_KEY(pkey, ec_key)) { EC_KEY_free(ec_key); CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_EVP_LIB); goto err; } } else { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, CPK_R_INVALID_PKEY_TYPE); goto err; } /* * add id to EVP_PKEY attributes */ /* if(!X509_NAME_get_text_by_NID(param->id, NID_organizationName, domain_id, sizeof(domain_id) - 1)) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_X509_LIB); goto err; } if (!EVP_PKEY_add1_attr_by_NID(pkey, NID_organizationName, MBSTRING_UTF8, (const unsigned char *)domain_id, strlen(domain_id))) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_X509_LIB); goto err; } if (!EVP_PKEY_add1_attr_by_NID(pkey, NID_commonName, MBSTRING_UTF8, (const unsigned char *)id, strlen(id))) { CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY, ERR_R_X509_LIB); goto err; } */ return pkey; err: if (pkey) EVP_PKEY_free(pkey); return NULL; }
static int test_EVP_PKEY_check(int i) { int ret = 0; const unsigned char *p; EVP_PKEY *pkey = NULL; #ifndef OPENSSL_NO_EC EC_KEY *eckey = NULL; #endif EVP_PKEY_CTX *ctx = NULL; EVP_PKEY_CTX *ctx2 = NULL; const APK_DATA *ak = &keycheckdata[i]; const unsigned char *input = ak->kder; size_t input_len = ak->size; int expected_id = ak->evptype; int expected_check = ak->check; int expected_pub_check = ak->pub_check; int expected_param_check = ak->param_check; int type = ak->type; BIO *pubkey = NULL; p = input; switch (type) { case 0: if (!TEST_ptr(pkey = d2i_AutoPrivateKey(NULL, &p, input_len)) || !TEST_ptr_eq(p, input + input_len) || !TEST_int_eq(EVP_PKEY_id(pkey), expected_id)) goto done; break; #ifndef OPENSSL_NO_EC case 1: if (!TEST_ptr(pubkey = BIO_new_mem_buf(input, input_len)) || !TEST_ptr(eckey = d2i_EC_PUBKEY_bio(pubkey, NULL)) || !TEST_ptr(pkey = EVP_PKEY_new()) || !TEST_true(EVP_PKEY_assign_EC_KEY(pkey, eckey))) goto done; break; case 2: if (!TEST_ptr(eckey = d2i_ECParameters(NULL, &p, input_len)) || !TEST_ptr_eq(p, input + input_len) || !TEST_ptr(pkey = EVP_PKEY_new()) || !TEST_true(EVP_PKEY_assign_EC_KEY(pkey, eckey))) goto done; break; #endif default: return 0; } if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL))) goto done; if (!TEST_int_eq(EVP_PKEY_check(ctx), expected_check)) goto done; if (!TEST_int_eq(EVP_PKEY_public_check(ctx), expected_pub_check)) goto done; if (!TEST_int_eq(EVP_PKEY_param_check(ctx), expected_param_check)) goto done; ctx2 = EVP_PKEY_CTX_new_id(0xdefaced, NULL); /* assign the pkey directly, as an internal test */ EVP_PKEY_up_ref(pkey); ctx2->pkey = pkey; if (!TEST_int_eq(EVP_PKEY_check(ctx2), 0xbeef)) goto done; if (!TEST_int_eq(EVP_PKEY_public_check(ctx2), 0xbeef)) goto done; if (!TEST_int_eq(EVP_PKEY_param_check(ctx2), 0xbeef)) goto done; ret = 1; done: EVP_PKEY_CTX_free(ctx); EVP_PKEY_CTX_free(ctx2); EVP_PKEY_free(pkey); BIO_free(pubkey); return ret; }
static LUA_FUNCTION(openssl_pkey_new) { EVP_PKEY *pkey = NULL; const char* alg = "rsa"; if (lua_isnoneornil(L, 1) || lua_isstring(L, 1)) { alg = luaL_optstring(L, 1, alg); if (strcasecmp(alg, "rsa") == 0) { int bits = luaL_optint(L, 2, 1024); int e = luaL_optint(L, 3, 65537); RSA* rsa = RSA_new(); BIGNUM *E = BN_new(); BN_set_word(E, e); if (RSA_generate_key_ex(rsa, bits, E, NULL)) { pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, rsa); } else RSA_free(rsa); BN_free(E); } else if (strcasecmp(alg, "dsa") == 0) { int bits = luaL_optint(L, 2, 1024); size_t seed_len = 0; const char* seed = luaL_optlstring(L, 3, NULL, &seed_len); DSA *dsa = DSA_new(); if (DSA_generate_parameters_ex(dsa, bits, (byte*)seed, seed_len, NULL, NULL, NULL) && DSA_generate_key(dsa)) { pkey = EVP_PKEY_new(); EVP_PKEY_assign_DSA(pkey, dsa); } else DSA_free(dsa); } else if (strcasecmp(alg, "dh") == 0) { int bits = luaL_optint(L, 2, 512); int generator = luaL_optint(L, 3, 2); DH* dh = DH_new(); if (DH_generate_parameters_ex(dh, bits, generator, NULL)) { if (DH_generate_key(dh)) { pkey = EVP_PKEY_new(); EVP_PKEY_assign_DH(pkey, dh); } else DH_free(dh); } else DH_free(dh); } #ifndef OPENSSL_NO_EC else if (strcasecmp(alg, "ec") == 0) { EC_KEY *ec = NULL; EC_GROUP *group = openssl_get_ec_group(L, 2, 3, 4); if (!group) luaL_error(L, "failed to get ec_group object"); ec = EC_KEY_new(); if (ec) { EC_KEY_set_group(ec, group); EC_GROUP_free(group); if (EC_KEY_generate_key(ec)) { pkey = EVP_PKEY_new(); EVP_PKEY_assign_EC_KEY(pkey, ec); } else EC_KEY_free(ec); } else EC_GROUP_free(group); } #endif else { luaL_error(L, "not support %s!!!!", alg); } } else if (lua_istable(L, 1)) { lua_getfield(L, 1, "alg"); alg = luaL_optstring(L, -1, alg); lua_pop(L, 1); if (strcasecmp(alg, "rsa") == 0) { pkey = EVP_PKEY_new(); if (pkey) { RSA *rsa = RSA_new(); if (rsa) { OPENSSL_PKEY_SET_BN(1, rsa, n); OPENSSL_PKEY_SET_BN(1, rsa, e); OPENSSL_PKEY_SET_BN(1, rsa, d); OPENSSL_PKEY_SET_BN(1, rsa, p); OPENSSL_PKEY_SET_BN(1, rsa, q); OPENSSL_PKEY_SET_BN(1, rsa, dmp1); OPENSSL_PKEY_SET_BN(1, rsa, dmq1); OPENSSL_PKEY_SET_BN(1, rsa, iqmp); if (rsa->n) { if (!EVP_PKEY_assign_RSA(pkey, rsa)) { EVP_PKEY_free(pkey); pkey = NULL; } } } } } else if (strcasecmp(alg, "dsa") == 0) { pkey = EVP_PKEY_new(); if (pkey) { DSA *dsa = DSA_new(); if (dsa) { OPENSSL_PKEY_SET_BN(-1, dsa, p); OPENSSL_PKEY_SET_BN(-1, dsa, q); OPENSSL_PKEY_SET_BN(-1, dsa, g); OPENSSL_PKEY_SET_BN(-1, dsa, priv_key); OPENSSL_PKEY_SET_BN(-1, dsa, pub_key); if (dsa->p && dsa->q && dsa->g) { if (!dsa->priv_key && !dsa->pub_key) { DSA_generate_key(dsa); } if (!EVP_PKEY_assign_DSA(pkey, dsa)) { EVP_PKEY_free(pkey); pkey = NULL; } } } } } else if (strcasecmp(alg, "dh") == 0) { pkey = EVP_PKEY_new(); if (pkey) { DH *dh = DH_new(); if (dh) { OPENSSL_PKEY_SET_BN(-1, dh, p); OPENSSL_PKEY_SET_BN(-1, dh, g); OPENSSL_PKEY_SET_BN(-1, dh, priv_key); OPENSSL_PKEY_SET_BN(-1, dh, pub_key); if (dh->p && dh->g) { if (!dh->pub_key) { DH_generate_key(dh); } if (!EVP_PKEY_assign_DH(pkey, dh)) { EVP_PKEY_free(pkey); pkey = NULL; } } } } } else if (strcasecmp(alg, "ec") == 0) { BIGNUM *d = NULL; BIGNUM *x = NULL; BIGNUM *y = NULL; BIGNUM *z = NULL; EC_GROUP *group = NULL; lua_getfield(L, -1, "ec_name"); lua_getfield(L, -2, "param_enc"); lua_getfield(L, -3, "conv_form"); group = openssl_get_ec_group(L, -3, -2, -1); lua_pop(L, 3); if (!group) { luaL_error(L, "get openssl.ec_group fail"); } EC_GET_FIELD(d); EC_GET_FIELD(x); EC_GET_FIELD(y); EC_GET_FIELD(z); pkey = EVP_PKEY_new(); if (pkey) { EC_KEY *ec = EC_KEY_new(); if (ec) { EC_KEY_set_group(ec, group); if (d) EC_KEY_set_private_key(ec, d); if (x != NULL && y != NULL) { EC_POINT *pnt = EC_POINT_new(group); if (z == NULL) EC_POINT_set_affine_coordinates_GFp(group, pnt, x, y, NULL); else EC_POINT_set_Jprojective_coordinates_GFp(group, pnt, x, y, z, NULL); EC_KEY_set_public_key(ec, pnt); } if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { EC_KEY_free(ec); EVP_PKEY_free(pkey); pkey = NULL; } if (d && !EC_KEY_check_key(ec)) { EC_KEY_generate_key_part(ec); } } } } } if (pkey) { PUSH_OBJECT(pkey, "openssl.evp_pkey"); return 1; } return 0; }
/*- * Positive and negative ECDSA testing through EVP interface: * - EVP_DigestSign (this is the one-shot version) * - EVP_DigestVerify * * Tests the library can successfully: * - create a key * - create a signature * - accept that signature * - reject that signature with a different public key * - reject that signature if its length is not correct * - reject that signature after modifying the message * - accept that signature after un-modifying the message * - reject that signature after modifying the signature * - accept that signature after un-modifying the signature */ static int test_builtin(int n) { EC_KEY *eckey_neg = NULL, *eckey = NULL; unsigned char dirt, offset, tbs[128]; unsigned char *sig = NULL; EVP_PKEY *pkey_neg = NULL, *pkey = NULL; EVP_MD_CTX *mctx = NULL; size_t sig_len; int nid, ret = 0; nid = curves[n].nid; /* skip built-in curves where ord(G) is not prime */ if (nid == NID_ipsec4 || nid == NID_ipsec3) { TEST_info("skipped: ECDSA unsupported for curve %s", OBJ_nid2sn(nid)); return 1; } TEST_info("testing ECDSA for curve %s", OBJ_nid2sn(nid)); if (!TEST_ptr(mctx = EVP_MD_CTX_new()) /* get some random message data */ || !TEST_true(RAND_bytes(tbs, sizeof(tbs))) /* real key */ || !TEST_ptr(eckey = EC_KEY_new_by_curve_name(nid)) || !TEST_true(EC_KEY_generate_key(eckey)) || !TEST_ptr(pkey = EVP_PKEY_new()) || !TEST_true(EVP_PKEY_assign_EC_KEY(pkey, eckey)) /* fake key for negative testing */ || !TEST_ptr(eckey_neg = EC_KEY_new_by_curve_name(nid)) || !TEST_true(EC_KEY_generate_key(eckey_neg)) || !TEST_ptr(pkey_neg = EVP_PKEY_new()) || !TEST_true(EVP_PKEY_assign_EC_KEY(pkey_neg, eckey_neg))) goto err; sig_len = ECDSA_size(eckey); if (!TEST_ptr(sig = OPENSSL_malloc(sig_len)) /* create a signature */ || !TEST_true(EVP_DigestSignInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_true(EVP_DigestSign(mctx, sig, &sig_len, tbs, sizeof(tbs))) || !TEST_int_le(sig_len, ECDSA_size(eckey)) /* negative test, verify with wrong key, 0 return */ || !TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey_neg)) || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 0) /* negative test, verify with wrong signature length, -1 return */ || !TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len - 1, tbs, sizeof(tbs)), -1) /* positive test, verify with correct key, 1 return */ || !TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1)) goto err; /* muck with the message, test it fails with 0 return */ tbs[0] ^= 1; if (!TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 0)) goto err; /* un-muck and test it verifies */ tbs[0] ^= 1; if (!TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1)) goto err; /*- * Muck with the ECDSA signature. The DER encoding is one of: * - 30 LL 02 .. * - 30 81 LL 02 .. * * - Sometimes this mucks with the high level DER sequence wrapper: * in that case, DER-parsing of the whole signature should fail. * * - Sometimes this mucks with the DER-encoding of ECDSA.r: * in that case, DER-parsing of ECDSA.r should fail. * * - Sometimes this mucks with the DER-encoding of ECDSA.s: * in that case, DER-parsing of ECDSA.s should fail. * * - Sometimes this mucks with ECDSA.r: * in that case, the signature verification should fail. * * - Sometimes this mucks with ECDSA.s: * in that case, the signature verification should fail. * * The usual case is changing the integer value of ECDSA.r or ECDSA.s. * Because the ratio of DER overhead to signature bytes is small. * So most of the time it will be one of the last two cases. * * In any case, EVP_PKEY_verify should not return 1 for valid. */ offset = tbs[0] % sig_len; dirt = tbs[1] ? tbs[1] : 1; sig[offset] ^= dirt; if (!TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_int_ne(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1)) goto err; /* un-muck and test it verifies */ sig[offset] ^= dirt; if (!TEST_true(EVP_MD_CTX_reset(mctx)) || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey)) || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1)) goto err; ret = 1; err: EVP_PKEY_free(pkey); EVP_PKEY_free(pkey_neg); EVP_MD_CTX_free(mctx); OPENSSL_free(sig); return ret; }
std::string CertificateManager::generateECDSACertificate () { EC_KEY *ec_key; std::shared_ptr <EC_GROUP> group; std::shared_ptr <EVP_PKEY> private_key; std::string pem; std::string ecdsaParameters, ecdsaKey; std::string certificateECDSA; ec_key = EC_KEY_new (); if (ec_key == nullptr) { GST_ERROR ("EC key not created"); return certificateECDSA; } group = std::shared_ptr <EC_GROUP> (EC_GROUP_new_by_curve_name ( NID_X9_62_prime256v1), [] (EC_GROUP * obj) { EC_GROUP_free (obj); }); EC_GROUP_set_asn1_flag (group.get(), OPENSSL_EC_NAMED_CURVE); if (group == nullptr) { EC_KEY_free (ec_key); GST_ERROR ("EC group not created"); return certificateECDSA; } if (EC_KEY_set_group (ec_key, group.get() ) == 0) { EC_KEY_free (ec_key); GST_ERROR ("Group not set to key"); return certificateECDSA; } if (EC_KEY_generate_key (ec_key) == 0) { EC_KEY_free (ec_key); GST_ERROR ("EC key not generated"); return certificateECDSA; } private_key = std::shared_ptr<EVP_PKEY> (EVP_PKEY_new (), [] (EVP_PKEY * obj) { EVP_PKEY_free (obj); }); if (private_key == nullptr) { EC_KEY_free (ec_key); GST_ERROR ("Private key not created"); return certificateECDSA; } if (EVP_PKEY_assign_EC_KEY (private_key.get(), ec_key) == 0) { EC_KEY_free (ec_key); GST_ERROR ("Private key not assigned"); return certificateECDSA; } pem = generateCertificate (private_key.get() ); if (pem.empty () ) { GST_WARNING ("Certificate not generated"); return certificateECDSA; } ecdsaKey = ECDSAKeyToPEMString (ec_key); ec_key = nullptr; ecdsaParameters = parametersToPEMString (group.get() ); certificateECDSA = ecdsaParameters + ecdsaKey + pem; return certificateECDSA; }
int dnskey_build_pkey(struct rr_dnskey *rr) { if (rr->pkey_built) return rr->pkey ? 1 : 0; rr->pkey_built = 1; if (algorithm_type(rr->algorithm) == ALG_RSA_FAMILY) { RSA *rsa; EVP_PKEY *pkey; unsigned int e_bytes; unsigned char *pk; int l; rsa = RSA_new(); if (!rsa) goto done; pk = (unsigned char *)rr->pubkey.data; l = rr->pubkey.length; e_bytes = *pk++; l--; if (e_bytes == 0) { if (l < 2) /* public key is too short */ goto done; e_bytes = (*pk++) << 8; e_bytes += *pk++; l -= 2; } if (l < e_bytes) /* public key is too short */ goto done; rsa->e = BN_bin2bn(pk, e_bytes, NULL); pk += e_bytes; l -= e_bytes; rsa->n = BN_bin2bn(pk, l, NULL); pkey = EVP_PKEY_new(); if (!pkey) goto done; if (!EVP_PKEY_set1_RSA(pkey, rsa)) goto done; rr->pkey = pkey; } else if (algorithm_type(rr->algorithm) == ALG_ECC_FAMILY) { EC_KEY *pubeckey; EVP_PKEY *pkey; unsigned char *pk; int l; BIGNUM *bn_x = NULL; BIGNUM *bn_y = NULL; if (rr->algorithm == ALG_ECDSAP256SHA256) { l = SHA256_DIGEST_LENGTH; pubeckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); } else if (rr->algorithm == ALG_ECDSAP384SHA384) { l = SHA384_DIGEST_LENGTH; pubeckey = EC_KEY_new_by_curve_name(NID_secp384r1); } else { goto done; } if (!pubeckey) goto done; if (rr->pubkey.length != 2*l) { goto done; } pk = (unsigned char *)rr->pubkey.data; bn_x = BN_bin2bn(pk, l, NULL); bn_y = BN_bin2bn(&pk[l], l, NULL); if (1 != EC_KEY_set_public_key_affine_coordinates(pubeckey, bn_x, bn_y)) { goto done; } pkey = EVP_PKEY_new(); if (!pkey) goto done; if (!EVP_PKEY_assign_EC_KEY(pkey, pubeckey)) goto done; rr->pkey = pkey; } done: if (!rr->pkey) { moan(rr->rr.file_name, rr->rr.line, "error building pkey"); } return rr->pkey ? 1 : 0; }
static EVP_PKEY *ssh_nistp_line_to_key(char *line) { EVP_PKEY *key; EC_KEY *ec_key; BIGNUM *x; BIGNUM *y; unsigned char decoded[OPENSSH_LINE_MAX]; int len; int flen; char *b, *c; int i; int nid; /* check allowed key size */ if (strncmp(line + 16, "256", 3) == 0) flen = 32, nid = NID_X9_62_prime256v1; else if (strncmp(line + 16, "384", 3) == 0) flen = 48, nid = NID_secp384r1; else if (strncmp(line + 16, "521", 3) == 0) flen = 66, nid = NID_secp521r1; else return NULL; /* find the mime-blob */ b = line; if (!b) return NULL; /* find the first whitespace */ while (*b && *b != ' ') b++; /* skip that whitespace */ b++; /* find the end of the blob / comment */ for (c = b; *c && *c != ' ' && 'c' != '\t' && *c != '\r' && *c != '\n'; c++) ; *c = 0; /* decode binary data */ if (sc_base64_decode(b, decoded, OPENSSH_LINE_MAX) < 0) return NULL; i = 0; /* get integer from blob */ len = (decoded[i] << 24) + (decoded[i + 1] << 16) + (decoded[i + 2] << 8) + (decoded[i + 3]); i += 4; /* always check 'len' to get safe 'i' as index into 'decoded' array */ if (len != 19) return NULL; /* check key type (must be same in decoded data and at line start) */ if (strncmp((char *)&decoded[i], line, 19) != 0) return NULL; i += len; /* get integer from blob */ len = (decoded[i] << 24) + (decoded[i + 1] << 16) + (decoded[i + 2] << 8) + (decoded[i + 3]); i += 4; /* check curve name - must match key type */ if(len != 8) return NULL; if (strncmp((char *)&decoded[i], line + 11, 8) != 0) return NULL; i += len; /* get integer from blob */ len = (decoded[i] << 24) + (decoded[i + 1] << 16) + (decoded[i + 2] << 8) + (decoded[i + 3]); i += 4; /* read public key (uncompressed point) */ /* test if data length is corresponding to key size */ if (len != 1 + flen * 2) return NULL; /* check uncompressed indicator */ if (decoded[i] != 4 ) return NULL; i++; /* create key */ ec_key = EC_KEY_new_by_curve_name(nid); /* read point coordinates */ x = BN_bin2bn(decoded + i, flen, NULL); i += flen; y = BN_bin2bn(decoded + i, flen, NULL); /* do error checking here: valid x, y, ec_key, point on curve.. */ if (!EC_KEY_set_public_key_affine_coordinates(ec_key, x, y)) { EC_KEY_free(ec_key); BN_free(x); BN_free(y); return NULL; } key = EVP_PKEY_new(); EVP_PKEY_assign_EC_KEY(key, ec_key); return key; }
/* * Create identity */ int build_identity(void) { EVP_PKEY * pkey ; RSA * rsa ; EC_KEY * ecc ; X509 * cert ; X509_NAME * name ; identity ca ; char filename[FIELD_SZ+5]; FILE * pem ; /* Check before overwriting */ sprintf(filename, "%s.crt", certinfo.cn); if (access(filename, F_OK)!=-1) { fprintf(stderr, "identity named %s already exists in this directory. Exiting now\n", filename); return -1 ; } sprintf(filename, "%s.key", certinfo.cn); if (access(filename, F_OK)!=-1) { fprintf(stderr, "identity named %s already exists in this directory. Exiting now\n", filename); return -1 ; } switch (certinfo.profile) { case PROFILE_ROOT_CA: strcpy(certinfo.ou, "Root"); break; case PROFILE_SUB_CA: strcpy(certinfo.ou, "Sub"); break; case PROFILE_SERVER: strcpy(certinfo.ou, "Server"); break; case PROFILE_CLIENT: strcpy(certinfo.ou, "Client"); break; case PROFILE_WWW: strcpy(certinfo.ou, "Server"); break; default: fprintf(stderr, "Unknown profile: aborting\n"); return -1 ; } if (certinfo.ec_name[0] && certinfo.profile!=PROFILE_CLIENT) { fprintf(stderr, "ECC keys are only supported for clients\n"); return -1 ; } if (certinfo.profile != PROFILE_ROOT_CA) { /* Need to load signing CA */ if (load_ca(certinfo.signing_ca, &ca)!=0) { fprintf(stderr, "Cannot find CA key or certificate\n"); return -1 ; } /* Organization is the same as root */ X509_NAME_get_text_by_NID(X509_get_subject_name(ca.cert), NID_organizationName, certinfo.o, FIELD_SZ); } /* Generate key pair */ if (certinfo.ec_name[0]) { printf("Generating EC key [%s]\n", certinfo.ec_name); ecc = EC_KEY_new_by_curve_name(OBJ_txt2nid(certinfo.ec_name)); if (!ecc) { fprintf(stderr, "Unknown curve: [%s]\n", certinfo.ec_name); return -1 ; } EC_KEY_set_asn1_flag(ecc, OPENSSL_EC_NAMED_CURVE); EC_KEY_generate_key(ecc); pkey = EVP_PKEY_new(); EVP_PKEY_assign_EC_KEY(pkey, ecc); } else { printf("Generating RSA-%d key\n", certinfo.rsa_keysz); pkey = EVP_PKEY_new(); rsa = RSA_generate_key(certinfo.rsa_keysz, RSA_F4, progress, 0); EVP_PKEY_assign_RSA(pkey, rsa); } /* Assign all certificate fields */ cert = X509_new(); X509_set_version(cert, 2); set_serial128(cert); X509_gmtime_adj(X509_get_notBefore(cert), 0); X509_gmtime_adj(X509_get_notAfter(cert), certinfo.days * 24*60*60); X509_set_pubkey(cert, pkey); name = X509_get_subject_name(cert); if (certinfo.c[0]) { X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (unsigned char*)certinfo.c, -1, -1, 0); } X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (unsigned char*)certinfo.o, -1, -1, 0); X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char*)certinfo.cn, -1, -1, 0); X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_ASC, (unsigned char*)certinfo.ou, -1, -1, 0); if (certinfo.l[0]) { X509_NAME_add_entry_by_txt(name, "L", MBSTRING_ASC, (unsigned char *)certinfo.l, -1, -1, 0); } if (certinfo.st[0]) { X509_NAME_add_entry_by_txt(name, "ST", MBSTRING_ASC, (unsigned char *)certinfo.st, -1, -1, 0); } /* Set extensions according to profile */ switch (certinfo.profile) { case PROFILE_ROOT_CA: /* CA profiles can issue certs and sign CRLS */ set_extension(cert, cert, NID_basic_constraints, "critical,CA:TRUE"); set_extension(cert, cert, NID_key_usage, "critical,keyCertSign,cRLSign"); set_extension(cert, cert, NID_subject_key_identifier, "hash"); set_extension(cert, cert, NID_authority_key_identifier, "keyid:always"); break ; case PROFILE_SUB_CA: /* CA profiles can issue certs and sign CRLS */ set_extension(ca.cert, cert, NID_basic_constraints, "critical,CA:TRUE"); set_extension(ca.cert, cert, NID_key_usage, "critical,keyCertSign,cRLSign"); set_extension(ca.cert, cert, NID_subject_key_identifier, "hash"); set_extension(ca.cert, cert, NID_authority_key_identifier, "keyid:always"); break; case PROFILE_CLIENT: if (certinfo.san[0]) { set_extension(ca.cert, cert, NID_subject_alt_name, certinfo.san); } set_extension(ca.cert, cert, NID_basic_constraints, "CA:FALSE"); set_extension(ca.cert, cert, NID_anyExtendedKeyUsage, "clientAuth"); set_extension(ca.cert, cert, NID_key_usage, "digitalSignature"); set_extension(ca.cert, cert, NID_subject_key_identifier, "hash"); set_extension(ca.cert, cert, NID_authority_key_identifier, "issuer:always,keyid:always"); break ; case PROFILE_SERVER: if (certinfo.san[0]) { set_extension(ca.cert, cert, NID_subject_alt_name, certinfo.san); } set_extension(ca.cert, cert, NID_basic_constraints, "CA:FALSE"); set_extension(ca.cert, cert, NID_netscape_cert_type, "server"); set_extension(ca.cert, cert, NID_anyExtendedKeyUsage, "serverAuth"); set_extension(ca.cert, cert, NID_key_usage, "digitalSignature,keyEncipherment"); set_extension(ca.cert, cert, NID_subject_key_identifier, "hash"); set_extension(ca.cert, cert, NID_authority_key_identifier, "issuer:always,keyid:always"); break ; case PROFILE_WWW: if (certinfo.san[0]) { set_extension(ca.cert, cert, NID_subject_alt_name, certinfo.san); } set_extension(ca.cert, cert, NID_basic_constraints, "CA:FALSE"); set_extension(ca.cert, cert, NID_netscape_cert_type, "server"); set_extension(ca.cert, cert, NID_anyExtendedKeyUsage, "serverAuth,clientAuth"); set_extension(ca.cert, cert, NID_key_usage, "digitalSignature,keyEncipherment"); set_extension(ca.cert, cert, NID_subject_key_identifier, "hash"); set_extension(ca.cert, cert, NID_authority_key_identifier, "issuer:always,keyid:always"); break; case PROFILE_UNKNOWN: default: break ; } /* Set issuer */ if (certinfo.profile==PROFILE_ROOT_CA) { /* Self-signed */ X509_set_issuer_name(cert, name); X509_sign(cert, pkey, EVP_sha256()); } else { /* Signed by parent CA */ X509_set_issuer_name(cert, X509_get_subject_name(ca.cert)); X509_sign(cert, ca.key, EVP_sha256()); } printf("Saving results to %s.[crt|key]\n", certinfo.cn); pem = fopen(filename, "wb"); PEM_write_PrivateKey(pem, pkey, NULL, NULL, 0, NULL, NULL); fclose(pem); sprintf(filename, "%s.crt", certinfo.cn); pem = fopen(filename, "wb"); PEM_write_X509(pem, cert); fclose(pem); X509_free(cert); EVP_PKEY_free(pkey); if (certinfo.profile!=PROFILE_ROOT_CA) { X509_free(ca.cert); EVP_PKEY_free(ca.key); } printf("done\n"); return 0; }
int FuzzerTestOneInput(const uint8_t *buf, size_t len) { SSL *server; BIO *in; BIO *out; #if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DSA) BIO *bio_buf; #endif SSL_CTX *ctx; int ret; RSA *privkey; const uint8_t *bufp; EVP_PKEY *pkey; X509 *cert; #ifndef OPENSSL_NO_EC EC_KEY *ecdsakey = NULL; #endif #ifndef OPENSSL_NO_DSA DSA *dsakey = NULL; #endif uint8_t opt; if (len < 2) return 0; /* * TODO: use the ossltest engine (optionally?) to disable crypto checks. */ /* This only fuzzes the initial flow from the client so far. */ ctx = SSL_CTX_new(SSLv23_method()); ret = SSL_CTX_set_min_proto_version(ctx, 0); OPENSSL_assert(ret == 1); ret = SSL_CTX_set_cipher_list(ctx, "ALL:eNULL:@SECLEVEL=0"); OPENSSL_assert(ret == 1); /* RSA */ bufp = kRSAPrivateKeyDER; privkey = d2i_RSAPrivateKey(NULL, &bufp, sizeof(kRSAPrivateKeyDER)); OPENSSL_assert(privkey != NULL); pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, privkey); ret = SSL_CTX_use_PrivateKey(ctx, pkey); OPENSSL_assert(ret == 1); EVP_PKEY_free(pkey); bufp = kCertificateDER; cert = d2i_X509(NULL, &bufp, sizeof(kCertificateDER)); OPENSSL_assert(cert != NULL); ret = SSL_CTX_use_certificate(ctx, cert); OPENSSL_assert(ret == 1); X509_free(cert); #ifndef OPENSSL_NO_EC /* ECDSA */ bio_buf = BIO_new(BIO_s_mem()); OPENSSL_assert((size_t)BIO_write(bio_buf, ECDSAPrivateKeyPEM, sizeof(ECDSAPrivateKeyPEM)) == sizeof(ECDSAPrivateKeyPEM)); ecdsakey = PEM_read_bio_ECPrivateKey(bio_buf, NULL, NULL, NULL); ERR_print_errors_fp(stderr); OPENSSL_assert(ecdsakey != NULL); BIO_free(bio_buf); pkey = EVP_PKEY_new(); EVP_PKEY_assign_EC_KEY(pkey, ecdsakey); ret = SSL_CTX_use_PrivateKey(ctx, pkey); OPENSSL_assert(ret == 1); EVP_PKEY_free(pkey); bio_buf = BIO_new(BIO_s_mem()); OPENSSL_assert((size_t)BIO_write(bio_buf, ECDSACertPEM, sizeof(ECDSACertPEM)) == sizeof(ECDSACertPEM)); cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); OPENSSL_assert(cert != NULL); BIO_free(bio_buf); ret = SSL_CTX_use_certificate(ctx, cert); OPENSSL_assert(ret == 1); X509_free(cert); #endif #ifndef OPENSSL_NO_DSA /* DSA */ bio_buf = BIO_new(BIO_s_mem()); OPENSSL_assert((size_t)BIO_write(bio_buf, DSAPrivateKeyPEM, sizeof(DSAPrivateKeyPEM)) == sizeof(DSAPrivateKeyPEM)); dsakey = PEM_read_bio_DSAPrivateKey(bio_buf, NULL, NULL, NULL); ERR_print_errors_fp(stderr); OPENSSL_assert(dsakey != NULL); BIO_free(bio_buf); pkey = EVP_PKEY_new(); EVP_PKEY_assign_DSA(pkey, dsakey); ret = SSL_CTX_use_PrivateKey(ctx, pkey); OPENSSL_assert(ret == 1); EVP_PKEY_free(pkey); bio_buf = BIO_new(BIO_s_mem()); OPENSSL_assert((size_t)BIO_write(bio_buf, DSACertPEM, sizeof(DSACertPEM)) == sizeof(DSACertPEM)); cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL); OPENSSL_assert(cert != NULL); BIO_free(bio_buf); ret = SSL_CTX_use_certificate(ctx, cert); OPENSSL_assert(ret == 1); X509_free(cert); #endif /* TODO: Set up support for SRP and PSK */ server = SSL_new(ctx); in = BIO_new(BIO_s_mem()); out = BIO_new(BIO_s_mem()); SSL_set_bio(server, in, out); SSL_set_accept_state(server); opt = (uint8_t)buf[len-1]; len--; OPENSSL_assert((size_t)BIO_write(in, buf, len) == len); if ((opt & 0x01) != 0) { do { char early_buf[16384]; size_t early_len; ret = SSL_read_early_data(server, early_buf, sizeof(early_buf), &early_len); if (ret != SSL_READ_EARLY_DATA_SUCCESS) break; } while (1); } if (SSL_do_handshake(server) == 1) { /* Keep reading application data until error or EOF. */ uint8_t tmp[1024]; for (;;) { if (SSL_read(server, tmp, sizeof(tmp)) <= 0) { break; } } } SSL_free(server); ERR_clear_error(); SSL_CTX_free(ctx); return 0; }