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;
}
示例#2
0
文件: sign.c 项目: dnstap/knot
/*!
 * \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(&params->rdata, ec_key);
	if (result != KNOT_EOK) {
		EC_KEY_free(ec_key);
		return result;
	}

	result = ecdsa_set_private_key(&params->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;
}
示例#3
0
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;
}
示例#4
0
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");
	}

}
示例#5
0
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;
}
示例#6
0
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");
	}
}
示例#7
0
文件: p_ec.c 项目: HungMingWu/libquic
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;
}
示例#8
0
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;
}
示例#10
0
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;
}
示例#11
0
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);
}
示例#12
0
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;
}
示例#13
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;
}
示例#14
0
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 );

}
示例#15
0
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;
}
示例#16
0
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;
	}
示例#17
0
文件: cpk_lib.c 项目: LiTianjue/GmSSL
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;
}
示例#18
0
文件: ossl_pkey_ec.c 项目: fi8on/ruby
/*  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;
}
示例#19
0
/*
 * 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;
}
示例#20
0
文件: cpk_lib.c 项目: LiTianjue/GmSSL
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;
}
示例#21
0
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;
}
示例#22
0
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;

}
示例#23
0
文件: ecdsatest.c 项目: tiran/openssl
/*-
 * 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;
}
示例#24
0
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;
}
示例#25
0
文件: dnskey.c 项目: jelu/validns
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;
}
示例#26
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;
}
示例#27
0
文件: 2cca.c 项目: randunel/2cca
/*
 * 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;
}
示例#28
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;
}