コード例 #1
0
ファイル: privkey_pkcs8.c プロジェクト: gnutls/gnutls
/**
 * gnutls_x509_privkey_export2_pkcs8:
 * @key: Holds the key
 * @format: the format of output params. One of PEM or DER.
 * @password: the password that will be used to encrypt the key.
 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
 * @out: will contain a private key PEM or DER encoded
 *
 * This function will export the private key to a PKCS8 structure.
 * Both RSA and DSA keys can be exported. For DSA keys we use
 * PKCS #11 definitions. If the flags do not specify the encryption
 * cipher, then the default 3DES (PBES2) will be used.
 *
 * The @password can be either ASCII or UTF-8 in the default PBES2
 * encryption schemas, or ASCII for the PKCS12 schemas.
 *
 * The output buffer is allocated using gnutls_malloc().
 *
 * If the structure is PEM encoded, it will have a header
 * of "BEGIN ENCRYPTED PRIVATE KEY" or "BEGIN PRIVATE KEY" if
 * encryption is not used.
 *
 * Returns: In case of failure a negative error code will be
 *   returned, and 0 on success.
 *
 * Since 3.1.3
 **/
int
gnutls_x509_privkey_export2_pkcs8(gnutls_x509_privkey_t key,
				  gnutls_x509_crt_fmt_t format,
				  const char *password,
				  unsigned int flags, gnutls_datum_t * out)
{
	ASN1_TYPE pkcs8_asn = NULL, pkey_info;
	int ret;
	gnutls_datum_t tmp = {NULL, 0};
	schema_id schema;

	if (key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	/* Get the private key info
	 * tmp holds the DER encoding.
	 */
	ret = encode_to_private_key_info(key, &tmp, &pkey_info);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	schema = _gnutls_pkcs_flags_to_schema(flags);

	if (((flags & GNUTLS_PKCS_PLAIN) || password == NULL)
	    && !(flags & GNUTLS_PKCS_NULL_PASSWORD)) {
		_gnutls_free_key_datum(&tmp);

		ret =
		    _gnutls_x509_export_int2(pkey_info, format,
					     PEM_UNENCRYPTED_PKCS8, out);

		asn1_delete_structure2(&pkey_info, ASN1_DELETE_FLAG_ZEROIZE);
	} else {
		asn1_delete_structure2(&pkey_info, ASN1_DELETE_FLAG_ZEROIZE);	/* we don't need it */

		ret =
		    encode_to_pkcs8_key(schema, &tmp, password,
					&pkcs8_asn);
		_gnutls_free_key_datum(&tmp);

		if (ret < 0) {
			gnutls_assert();
			return ret;
		}

		ret =
		    _gnutls_x509_export_int2(pkcs8_asn, format, PEM_PKCS8,
					     out);

		asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
	}

	return ret;
}
コード例 #2
0
ファイル: privkey.c プロジェクト: Drakey83/steamlink-sdk
void _gnutls_x509_privkey_reinit(gnutls_x509_privkey_t key)
{
	gnutls_pk_params_clear(&key->params);
	gnutls_pk_params_release(&key->params);
	asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);
	key->key = ASN1_TYPE_EMPTY;
}
コード例 #3
0
ファイル: privkey_pkcs8.c プロジェクト: gnutls/gnutls
static int check_for_decrypted(const gnutls_datum_t *der)
{
	int result;
	ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.pkcs-8-PrivateKeyInfo",
				 &pkcs8_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	result = _asn1_strict_der_decode(&pkcs8_asn, der->data, der->size, NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result = 0;
 error:
	asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
	return result;

}
コード例 #4
0
ファイル: privkey.c プロジェクト: Drakey83/steamlink-sdk
/**
 * gnutls_x509_privkey_fix:
 * @key: Holds the key
 *
 * This function will recalculate the secondary parameters in a key.
 * In RSA keys, this can be the coefficient and exponent1,2.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int gnutls_x509_privkey_fix(gnutls_x509_privkey_t key)
{
	int ret;

	if (key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);

	ret =
	    _gnutls_asn1_encode_privkey(key->pk_algorithm, &key->key,
					&key->params);
	if (ret < 0) {
		gnutls_assert();
		return ret;
	}

	return 0;
}
コード例 #5
0
ファイル: privkey_pkcs8.c プロジェクト: gnutls/gnutls
/* Converts a PKCS #8 key to
 * an internal structure (gnutls_private_key)
 * (normally a PKCS #1 encoded RSA key)
 */
static int
pkcs8_key_decode(const gnutls_datum_t * raw_key,
		 const char *password, gnutls_x509_privkey_t pkey,
		 unsigned int decrypt)
{
	int result;
	ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
				 &pkcs8_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result =
	    _asn1_strict_der_decode(&pkcs8_asn, raw_key->data, raw_key->size,
			      NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	if (decrypt)
		result =
		    pkcs8_key_decrypt(raw_key, pkcs8_asn, password, pkey);
	else
		result = 0;

      error:
	asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
	return result;

}
コード例 #6
0
ファイル: key_encode.c プロジェクト: scorp2kk/steamlink-sdk
/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
 */
static int
_gnutls_asn1_encode_dsa(ASN1_TYPE * c2, gnutls_pk_params_st * params)
{
    int result, ret;
    const uint8_t null = '\0';

    /* first make sure that no previously allocated data are leaked */
    if (*c2 != ASN1_TYPE_EMPTY) {
        asn1_delete_structure(c2);
        *c2 = ASN1_TYPE_EMPTY;
    }

    if ((result = asn1_create_element
                  (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPrivateKey", c2))
            != ASN1_SUCCESS) {
        gnutls_assert();
        return _gnutls_asn2err(result);
    }

    /* Write PRIME
     */
    ret =
        _gnutls_x509_write_int(*c2, "p",
                               params->params[DSA_P], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_int(*c2, "q",
                               params->params[DSA_Q], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_int(*c2, "g",
                               params->params[DSA_G], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_int(*c2, "Y",
                               params->params[DSA_Y], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "priv",
                                   params->params[DSA_X], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    if ((result =
                asn1_write_value(*c2, "version", &null, 1)) != ASN1_SUCCESS) {
        gnutls_assert();
        ret = _gnutls_asn2err(result);
        goto cleanup;
    }

    return 0;

cleanup:
    asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);

    return ret;
}
コード例 #7
0
ファイル: privkey_pkcs8.c プロジェクト: gnutls/gnutls
/* Encodes a private key to the raw format PKCS #8 needs.
 * For RSA it is a PKCS #1 DER private key and for DSA it is
 * an ASN.1 INTEGER of the x value.
 */
inline static int
_encode_privkey(gnutls_x509_privkey_t pkey, gnutls_datum_t * raw)
{
	int ret;
	ASN1_TYPE spk = ASN1_TYPE_EMPTY;

	switch (pkey->params.algo) {
	case GNUTLS_PK_EDDSA_ED25519:
		/* we encode as octet string (which is going to be stored inside
		 * another octet string). No comments. */
		ret = _gnutls_x509_encode_string(ASN1_ETYPE_OCTET_STRING,
						 pkey->params.raw_priv.data, pkey->params.raw_priv.size,
						 raw);
		if (ret < 0)
			gnutls_assert();
		return ret;

	case GNUTLS_PK_GOST_01:
	case GNUTLS_PK_GOST_12_256:
	case GNUTLS_PK_GOST_12_512:
		if ((ret = asn1_create_element
					(_gnutls_get_gnutls_asn(), "GNUTLS.GOSTPrivateKey", &spk))
				!= ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto error;
		}

		ret = _gnutls_x509_write_key_int_le(spk, "", pkey->params.params[GOST_K]);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}

		ret = _gnutls_x509_der_encode(spk, "", raw, 0);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}

		asn1_delete_structure2(&spk, ASN1_DELETE_FLAG_ZEROIZE);
		break;

	case GNUTLS_PK_RSA:
	case GNUTLS_PK_RSA_PSS:
	case GNUTLS_PK_ECDSA:
		ret =
		    _gnutls_x509_export_int2(pkey->key, GNUTLS_X509_FMT_DER,
					     "", raw);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}

		break;
	case GNUTLS_PK_DSA:
		/* DSAPublicKey == INTEGER */
		if ((ret = asn1_create_element
		     (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey",
		      &spk))
		    != ASN1_SUCCESS) {
			gnutls_assert();
			return _gnutls_asn2err(ret);
		}

		ret =
		    _gnutls_x509_write_int(spk, "", pkey->params.params[4],
					   1);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
		ret = _gnutls_x509_der_encode(spk, "", raw, 0);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}

		asn1_delete_structure2(&spk, ASN1_DELETE_FLAG_ZEROIZE);
		break;

	default:
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	return 0;

      error:
	asn1_delete_structure2(&spk, ASN1_DELETE_FLAG_ZEROIZE);
	asn1_delete_structure(&spk);
	return ret;

}
コード例 #8
0
ファイル: privkey.c プロジェクト: Drakey83/steamlink-sdk
/* Converts an ECC key to
 * an internal structure (gnutls_private_key)
 */
int
_gnutls_privkey_decode_ecc_key(ASN1_TYPE* pkey_asn, const gnutls_datum_t * raw_key,
			       gnutls_x509_privkey_t pkey, gnutls_ecc_curve_t curve)
{
	int ret;
	unsigned int version;
	char oid[MAX_OID_SIZE];
	int oid_size;
	gnutls_datum out;

	gnutls_pk_params_init(&pkey->params);

	pkey->params.algo = GNUTLS_PK_EC;
	if ((ret =
	     asn1_create_element(_gnutls_get_gnutls_asn(),
				 "GNUTLS.ECPrivateKey",
				 pkey_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(ret);
	}

	ret =
	    asn1_der_decoding(pkey_asn, raw_key->data, raw_key->size,
			      NULL);
	if (ret != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(ret);
		goto error;
	}

	ret = _gnutls_x509_read_uint(*pkey_asn, "Version", &version);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	if (version != 1) {
		_gnutls_debug_log
		    ("ECC private key version %u is not supported\n",
		     version);
		gnutls_assert();
		ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
		goto error;
	}

	/* read the curve */
	if (curve == GNUTLS_ECC_CURVE_INVALID) {
		oid_size = sizeof(oid);
		ret =
		    asn1_read_value(*pkey_asn, "parameters.namedCurve", oid,
			    &oid_size);
		if (ret != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto error;
		}

		pkey->params.flags = _gnutls_oid_to_ecc_curve(oid);

		if (pkey->params.flags == GNUTLS_ECC_CURVE_INVALID) {
			_gnutls_debug_log("Curve %s is not supported\n", oid);
			gnutls_assert();
			ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
			goto error;
		}
	} else {
		pkey->params.flags = curve;
	}


	/* read the public key */
	ret = _gnutls_x509_read_value(*pkey_asn, "publicKey", &out);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	ret =
	    _gnutls_ecc_ansi_x963_import(out.data, out.size,
					 &pkey->params.params[ECC_X],
					 &pkey->params.params[ECC_Y]);

	_gnutls_free_datum(&out);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr += 2;

	/* read the private key */
	ret =
	    _gnutls_x509_read_key_int(*pkey_asn, "privateKey",
				  &pkey->params.params[ECC_K]);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	return 0;

      error:
	asn1_delete_structure2(pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
	gnutls_pk_params_clear(&pkey->params);
	gnutls_pk_params_release(&pkey->params);
	return ret;

}
コード例 #9
0
ファイル: privkey_pkcs8.c プロジェクト: gnutls/gnutls
/* 
 * Encodes a PKCS #1 private key to a PKCS #8 private key
 * info. The output will be allocated and stored into der. Also
 * the ASN1_TYPE of private key info will be returned.
 */
static int
encode_to_private_key_info(gnutls_x509_privkey_t pkey,
			   gnutls_datum_t * der, ASN1_TYPE * pkey_info)
{
	int result, len;
	uint8_t null = 0;
	const char *oid;
	gnutls_datum_t algo_params = { NULL, 0 };
	gnutls_datum_t algo_privkey = { NULL, 0 };

	oid = gnutls_pk_get_oid(pkey->params.algo);
	if (oid == NULL) {
		gnutls_assert();
		return GNUTLS_E_UNIMPLEMENTED_FEATURE;
	}

	result =
	    _gnutls_x509_write_pubkey_params(&pkey->params, &algo_params);
	if (result < 0) {
		gnutls_assert();
		return result;
	}

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.pkcs-8-PrivateKeyInfo",
				 pkey_info)) != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* Write the version.
	 */
	result = asn1_write_value(*pkey_info, "version", &null, 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* write the privateKeyAlgorithm
	 * fields. (OID+NULL data)
	 */
	result =
	    asn1_write_value(*pkey_info, "privateKeyAlgorithm.algorithm",
			     oid, 1);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result =
	    asn1_write_value(*pkey_info, "privateKeyAlgorithm.parameters",
			     algo_params.data, algo_params.size);
	_gnutls_free_key_datum(&algo_params);

	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}


	/* Write the raw private key
	 */
	result = _encode_privkey(pkey, &algo_privkey);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	result =
	    asn1_write_value(*pkey_info, "privateKey", algo_privkey.data,
			     algo_privkey.size);
	_gnutls_free_key_datum(&algo_privkey);

	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	if ((pkey->params.pkflags & GNUTLS_PK_FLAG_PROVABLE) && pkey->params.seed_size > 0) {
		gnutls_datum_t seed_info;
		/* rfc8479 attribute encoding */

		result = _x509_encode_provable_seed(pkey, &seed_info);
		if (result < 0) {
			gnutls_assert();
			goto error;
		}

		result = _x509_set_attribute(*pkey_info, "attributes", OID_ATTR_PROV_SEED, &seed_info);
		gnutls_free(seed_info.data);
		if (result < 0) {
			gnutls_assert();
			goto error;
		}
	} else {
		/* Append an empty Attributes field.
		 */
		result = asn1_write_value(*pkey_info, "attributes", NULL, 0);
		if (result != ASN1_SUCCESS) {
			gnutls_assert();
			result = _gnutls_asn2err(result);
			goto error;
		}
	}

	/* DER Encode the generated private key info.
	 */
	len = 0;
	result = asn1_der_coding(*pkey_info, "", NULL, &len, NULL);
	if (result != ASN1_MEM_ERROR) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* allocate data for the der
	 */
	der->size = len;
	der->data = gnutls_malloc(len);
	if (der->data == NULL) {
		gnutls_assert();
		return GNUTLS_E_MEMORY_ERROR;
	}

	result = asn1_der_coding(*pkey_info, "", der->data, &len, NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	return 0;

      error:
	asn1_delete_structure2(pkey_info, ASN1_DELETE_FLAG_ZEROIZE);
	_gnutls_free_datum(&algo_params);
	_gnutls_free_key_datum(&algo_privkey);
	return result;

}
コード例 #10
0
ファイル: privkey_pkcs8.c プロジェクト: gnutls/gnutls
/* Converts a PKCS #8 private key info to
 * a PKCS #8 EncryptedPrivateKeyInfo.
 */
static int
encode_to_pkcs8_key(schema_id schema, const gnutls_datum_t * der_key,
		    const char *password, ASN1_TYPE * out)
{
	int result;
	gnutls_datum_t key = { NULL, 0 };
	gnutls_datum_t tmp = { NULL, 0 };
	ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;
	struct pbkdf2_params kdf_params;
	struct pbe_enc_params enc_params;
	const struct pkcs_cipher_schema_st *s;

	s = _gnutls_pkcs_schema_get(schema);
	if (s == NULL || s->decrypt_only) {
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
	}

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
				 &pkcs8_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	/* Write the encryption schema OID
	 */
	result =
	    asn1_write_value(pkcs8_asn, "encryptionAlgorithm.algorithm",
			     s->write_oid, 1);

	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* Generate a symmetric key.
	 */

	result =
	    _gnutls_pkcs_generate_key(schema, password, &kdf_params, &enc_params, &key);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	result =
	    _gnutls_pkcs_write_schema_params(schema, pkcs8_asn,
				"encryptionAlgorithm.parameters",
				&kdf_params, &enc_params);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	/* Parameters have been encoded. Now
	 * encrypt the Data.
	 */
	result = _gnutls_pkcs_raw_encrypt_data(der_key, &enc_params, &key, &tmp);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	/* write the encrypted data.
	 */
	result =
	    asn1_write_value(pkcs8_asn, "encryptedData", tmp.data,
			     tmp.size);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	_gnutls_free_datum(&tmp);
	_gnutls_free_key_datum(&key);

	*out = pkcs8_asn;

	return 0;

      error:
	_gnutls_free_key_datum(&key);
	_gnutls_free_datum(&tmp);
	asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
	return result;
}
コード例 #11
0
ファイル: privkey_pkcs8.c プロジェクト: gnutls/gnutls
static int
decode_private_key_info(const gnutls_datum_t * der,
			gnutls_x509_privkey_t pkey)
{
	int result, len;
	char oid[MAX_OID_SIZE];
	ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;
	gnutls_datum_t sder;
	int ret;

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.pkcs-8-PrivateKeyInfo",
				 &pkcs8_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result = _asn1_strict_der_decode(&pkcs8_asn, der->data, der->size, NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* Check the private key algorithm OID
	 */
	len = sizeof(oid);
	result =
	    asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.algorithm",
			    oid, &len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	pkey->params.algo = gnutls_oid_to_pk(oid);
	if (pkey->params.algo == GNUTLS_PK_UNKNOWN) {
		gnutls_assert();
		_gnutls_debug_log
		    ("PKCS #8 private key OID '%s' is unsupported.\n",
		     oid);
		result = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
		goto error;
	}

	/* Get the DER encoding of the actual private key.
	 */

	switch(pkey->params.algo) {
		case GNUTLS_PK_RSA:
			result = _decode_pkcs8_rsa_key(pkcs8_asn, pkey);
			break;
		case GNUTLS_PK_RSA_PSS:
			result = _decode_pkcs8_rsa_pss_key(pkcs8_asn, pkey);
			break;
		case GNUTLS_PK_DSA:
			result = _decode_pkcs8_dsa_key(pkcs8_asn, pkey);
			break;
		case GNUTLS_PK_ECDSA:
			result = _decode_pkcs8_ecc_key(pkcs8_asn, pkey);
			break;
		case GNUTLS_PK_EDDSA_ED25519:
			result = _decode_pkcs8_eddsa_key(pkcs8_asn, pkey, oid);
			break;
		case GNUTLS_PK_GOST_01:
		case GNUTLS_PK_GOST_12_256:
		case GNUTLS_PK_GOST_12_512:
			result = _decode_pkcs8_gost_key(pkcs8_asn,
							pkey, pkey->params.algo);
			break;
		default:
			result = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
			goto error;
	}

	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	/* check for provable parameters attribute */
	ret = _x509_parse_attribute(pkcs8_asn, "attributes", OID_ATTR_PROV_SEED, 0, 1, &sder);
	if (ret >= 0) { /* ignore it when not being present */
		ret = _x509_decode_provable_seed(pkey, &sder);
		gnutls_free(sder.data);
		if (ret < 0) {
			gnutls_assert();
		}
	}

	result = 0;

error:
	asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
	return result;

}
コード例 #12
0
ファイル: privkey_pkcs8.c プロジェクト: gnutls/gnutls
/**
 * gnutls_x509_privkey_import_pkcs8:
 * @key: The data to store the parsed key
 * @data: The DER or PEM encoded key.
 * @format: One of DER or PEM
 * @password: the password to decrypt the key (if it is encrypted).
 * @flags: 0 if encrypted or GNUTLS_PKCS_PLAIN if not encrypted.
 *
 * This function will convert the given DER or PEM encoded PKCS8 2.0
 * encrypted key to the native gnutls_x509_privkey_t format. The
 * output will be stored in @key.  Both RSA and DSA keys can be
 * imported, and flags can only be used to indicate an unencrypted
 * key.
 *
 * The @password can be either ASCII or UTF-8 in the default PBES2
 * encryption schemas, or ASCII for the PKCS12 schemas.
 *
 * If the Certificate is PEM encoded it should have a header of
 * "ENCRYPTED PRIVATE KEY", or "PRIVATE KEY". You only need to
 * specify the flags if the key is DER encoded, since in that case
 * the encryption status cannot be auto-detected.
 *
 * If the %GNUTLS_PKCS_PLAIN flag is specified and the supplied data
 * are encrypted then %GNUTLS_E_DECRYPTION_FAILED is returned.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_privkey_import_pkcs8(gnutls_x509_privkey_t key,
				 const gnutls_datum_t * data,
				 gnutls_x509_crt_fmt_t format,
				 const char *password, unsigned int flags)
{
	int result = 0, need_free = 0;
	gnutls_datum_t _data;

	if (key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	_data.data = data->data;
	_data.size = data->size;

	key->params.algo = GNUTLS_PK_UNKNOWN;

	/* If the Certificate is in PEM format then decode it
	 */
	if (format == GNUTLS_X509_FMT_PEM) {
		/* Try the first header 
		 */
		result =
		    _gnutls_fbase64_decode(PEM_UNENCRYPTED_PKCS8,
					   data->data, data->size, &_data);

		if (result < 0) {	/* Try the encrypted header 
					 */
			result =
			    _gnutls_fbase64_decode(PEM_PKCS8, data->data,
						   data->size, &_data);

			if (result < 0) {
				gnutls_assert();
				return result;
			}
		} else if (flags == 0)
			flags |= GNUTLS_PKCS_PLAIN;

		need_free = 1;
	}

	if (key->expanded) {
		_gnutls_x509_privkey_reinit(key);
	}
	key->expanded = 1;

	/* Here we don't check for password == NULL to maintain a backwards
	 * compatibility behavior, with old versions that were encrypting using
	 * a NULL password.
	 */
	if (flags & GNUTLS_PKCS_PLAIN) {
		result = decode_private_key_info(&_data, key);
		if (result < 0) {	/* check if it is encrypted */
			if (pkcs8_key_decode(&_data, "", key, 0) == 0)
				result = GNUTLS_E_DECRYPTION_FAILED;
		}
	} else {		/* encrypted. */
		result = pkcs8_key_decode(&_data, password, key, 1);
	}

	if (result < 0) {
		gnutls_assert();
		goto cleanup;
	}

	/* This part is necessary to get the public key on certain algorithms.
	 * In the import above we only get the private key. */
	result =
	    _gnutls_pk_fixup(key->params.algo, GNUTLS_IMPORT, &key->params);
	if (result < 0) {
		gnutls_assert();
		goto cleanup;
	}

	if (need_free)
		_gnutls_free_datum(&_data);

	/* The key has now been decoded.
	 */
	return 0;

 cleanup:
	asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);
	key->params.algo = GNUTLS_PK_UNKNOWN;
	if (need_free)
		_gnutls_free_datum(&_data);
	return result;
}
コード例 #13
0
ファイル: privkey.c プロジェクト: Drakey83/steamlink-sdk
static ASN1_TYPE
decode_dsa_key(const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey)
{
	int result;
	ASN1_TYPE dsa_asn;

	if ((result =
	     asn1_create_element(_gnutls_get_gnutls_asn(),
				 "GNUTLS.DSAPrivateKey",
				 &dsa_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return NULL;
	}

	gnutls_pk_params_init(&pkey->params);

	pkey->params.algo = GNUTLS_PK_DSA;

	result =
	    asn1_der_decoding(&dsa_asn, raw_key->data, raw_key->size,
			      NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		goto error;
	}

	if ((result =
	     _gnutls_x509_read_int(dsa_asn, "p",
				   &pkey->params.params[0])) < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result =
	     _gnutls_x509_read_int(dsa_asn, "q",
				   &pkey->params.params[1])) < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result =
	     _gnutls_x509_read_int(dsa_asn, "g",
				   &pkey->params.params[2])) < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result =
	     _gnutls_x509_read_int(dsa_asn, "Y",
				   &pkey->params.params[3])) < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result = _gnutls_x509_read_key_int(dsa_asn, "priv",
					    &pkey->params.params[4])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	return dsa_asn;

      error:
	asn1_delete_structure2(&dsa_asn, ASN1_DELETE_FLAG_ZEROIZE);
	gnutls_pk_params_clear(&pkey->params);
	gnutls_pk_params_release(&pkey->params);
	return NULL;

}
コード例 #14
0
ファイル: privkey_pkcs8.c プロジェクト: gnutls/gnutls
static
int pkcs8_key_info(const gnutls_datum_t * raw_key,
		   const struct pkcs_cipher_schema_st **p,
		   struct pbkdf2_params *kdf_params,
		   char **oid)
{
	int result, len;
	char enc_oid[MAX_OID_SIZE*2];
	int params_start, params_end, params_len;
	struct pbe_enc_params enc_params;
	schema_id schema;
	ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;

	memset(&enc_params, 0, sizeof(enc_params));

	result = check_for_decrypted(raw_key);
	if (result == 0)
		return GNUTLS_E_INVALID_REQUEST;

	if ((result =
	     asn1_create_element(_gnutls_get_pkix(),
				 "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
				 &pkcs8_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	result =
	    _asn1_strict_der_decode(&pkcs8_asn, raw_key->data, raw_key->size,
			      NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}

	/* Check the encryption schema OID
	 */
	len = sizeof(enc_oid);
	result =
	    asn1_read_value(pkcs8_asn, "encryptionAlgorithm.algorithm",
			    enc_oid, &len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		goto error;
	}

	if (oid) {
		*oid = gnutls_strdup(enc_oid);
	}

	if ((result = _gnutls_check_pkcs_cipher_schema(enc_oid)) < 0) {
		gnutls_assert();
		goto error;
	}

	schema = result;

	/* Get the DER encoding of the parameters.
	 */
	result =
	    asn1_der_decoding_startEnd(pkcs8_asn, raw_key->data,
				       raw_key->size,
				       "encryptionAlgorithm.parameters",
				       &params_start, &params_end);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		result = _gnutls_asn2err(result);
		goto error;
	}
	params_len = params_end - params_start + 1;

	result =
	    _gnutls_read_pkcs_schema_params(&schema, NULL,
				    &raw_key->data[params_start],
				    params_len, kdf_params, &enc_params);

	if (result < 0) {
		gnutls_assert();
		if (oid && enc_params.pbes2_oid[0] != 0) {
			snprintf(enc_oid, sizeof(enc_oid), "%s/%s", *oid, enc_params.pbes2_oid);
			gnutls_free(*oid);
			*oid = gnutls_strdup(enc_oid);
		}
		goto error;
	}

	*p = _gnutls_pkcs_schema_get(schema);
	if (*p == NULL) {
		gnutls_assert();
		result = GNUTLS_E_UNKNOWN_CIPHER_TYPE;
		goto error;
	}

	result = 0;

      error:
	asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
	return result;
}
コード例 #15
0
ファイル: key_encode.c プロジェクト: scorp2kk/steamlink-sdk
/* Encodes the ECC parameters into an ASN.1 ECPrivateKey structure.
 */
static int
_gnutls_asn1_encode_ecc(ASN1_TYPE * c2, gnutls_pk_params_st * params)
{
    int ret;
    uint8_t one = '\x01';
    gnutls_datum pubkey = { NULL, 0 };
    const char *oid;

    oid = _gnutls_ecc_curve_get_oid(params->flags);

    if (params->params_nr != ECC_PRIVATE_PARAMS || oid == NULL)
        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

    ret =
        _gnutls_ecc_ansi_x963_export(params->flags,
                                     params->params[ECC_X],
                                     params->params[ECC_Y], &pubkey);
    if (ret < 0)
        return gnutls_assert_val(ret);

    /* Ok. Now we have the data. Create the asn1 structures
     */

    /* first make sure that no previously allocated data are leaked */
    if (*c2 != ASN1_TYPE_EMPTY) {
        asn1_delete_structure(c2);
        *c2 = ASN1_TYPE_EMPTY;
    }

    if ((ret = asn1_create_element
               (_gnutls_get_gnutls_asn(), "GNUTLS.ECPrivateKey", c2))
            != ASN1_SUCCESS) {
        gnutls_assert();
        ret = _gnutls_asn2err(ret);
        goto cleanup;
    }

    if ((ret =
                asn1_write_value(*c2, "Version", &one, 1)) != ASN1_SUCCESS) {
        gnutls_assert();
        ret = _gnutls_asn2err(ret);
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "privateKey",
                                   params->params[ECC_K], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    if ((ret =
                asn1_write_value(*c2, "publicKey", pubkey.data,
                                 pubkey.size * 8)) != ASN1_SUCCESS) {
        gnutls_assert();
        ret = _gnutls_asn2err(ret);
        goto cleanup;
    }

    /* write our choice */
    if ((ret =
                asn1_write_value(*c2, "parameters", "namedCurve",
                                 1)) != ASN1_SUCCESS) {
        gnutls_assert();
        ret = _gnutls_asn2err(ret);
        goto cleanup;
    }

    if ((ret =
                asn1_write_value(*c2, "parameters.namedCurve", oid,
                                 1)) != ASN1_SUCCESS) {
        gnutls_assert();
        ret = _gnutls_asn2err(ret);
        goto cleanup;
    }

    _gnutls_free_datum(&pubkey);
    return 0;

cleanup:
    asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);
    _gnutls_free_datum(&pubkey);

    return ret;
}
コード例 #16
0
ファイル: key_encode.c プロジェクト: scorp2kk/steamlink-sdk
/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
 */
static int
_gnutls_asn1_encode_rsa(ASN1_TYPE * c2, gnutls_pk_params_st * params)
{
    int result, ret;
    uint8_t null = '\0';
    gnutls_pk_params_st pk_params;

    /* we do copy the parameters into a new structure to run _gnutls_pk_fixup,
     * i.e., regenerate some parameters in case they were broken */
    gnutls_pk_params_init(&pk_params);

    ret = _gnutls_pk_params_copy(&pk_params, params);
    if (ret < 0) {
        gnutls_assert();
        return ret;
    }

    ret =
        _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    /* Ok. Now we have the data. Create the asn1 structures
     */

    /* first make sure that no previously allocated data are leaked */
    if (*c2 != ASN1_TYPE_EMPTY) {
        asn1_delete_structure(c2);
        *c2 = ASN1_TYPE_EMPTY;
    }

    if ((result = asn1_create_element
                  (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPrivateKey", c2))
            != ASN1_SUCCESS) {
        gnutls_assert();
        ret = _gnutls_asn2err(result);
        goto cleanup;
    }

    /* Write PRIME
     */
    ret =
        _gnutls_x509_write_int(*c2, "modulus",
                               params->params[RSA_MODULUS], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_int(*c2, "publicExponent",
                               params->params[RSA_PUB], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "privateExponent",
                                   params->params[RSA_PRIV], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "prime1",
                                   params->params[RSA_PRIME1], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "prime2",
                                   params->params[RSA_PRIME2], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "coefficient",
                                   params->params[RSA_COEF], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "exponent1",
                                   params->params[RSA_E1], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    ret =
        _gnutls_x509_write_key_int(*c2, "exponent2",
                                   params->params[RSA_E2], 1);
    if (ret < 0) {
        gnutls_assert();
        goto cleanup;
    }

    if ((result = asn1_write_value(*c2, "otherPrimeInfos",
                                   NULL, 0)) != ASN1_SUCCESS) {
        gnutls_assert();
        ret = _gnutls_asn2err(result);
        goto cleanup;
    }

    if ((result =
                asn1_write_value(*c2, "version", &null, 1)) != ASN1_SUCCESS) {
        gnutls_assert();
        ret = _gnutls_asn2err(result);
        goto cleanup;
    }

    ret = 0;

cleanup:
    if (ret < 0)
        asn1_delete_structure2(c2, ASN1_DELETE_FLAG_ZEROIZE);

    gnutls_pk_params_clear(&pk_params);
    gnutls_pk_params_release(&pk_params);
    return ret;
}
コード例 #17
0
int _gnutls_read_pbkdf1_params(const uint8_t * data, int data_size,
		       struct pbkdf2_params *kdf_params,
		       struct pbe_enc_params *enc_params)
{
	ASN1_TYPE pasn = ASN1_TYPE_EMPTY;
	int len;
	int ret, result;

	memset(kdf_params, 0, sizeof(*kdf_params));
	memset(enc_params, 0, sizeof(*enc_params));

	if ((result =
		     asn1_create_element(_gnutls_get_pkix(),
					 "PKIX1.pkcs-5-PBE-params",
					 &pasn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return _gnutls_asn2err(result);
	}

	/* Decode the parameters.
	 */
	result =
	    _asn1_strict_der_decode(&pasn, data, data_size, NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto error;
	}

	ret =
	    _gnutls_x509_read_uint(pasn, "iterationCount",
			   &kdf_params->iter_count);
	if (ret < 0) {
		gnutls_assert();
		goto error;
	}

	if (kdf_params->iter_count >= MAX_ITER_COUNT || kdf_params->iter_count == 0) {
		ret = gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
		goto error;
	}

	len = sizeof(kdf_params->salt);
	result =
	    asn1_read_value(pasn, "salt",
		    kdf_params->salt, &len);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		ret = _gnutls_asn2err(result);
		goto error;
	}

	if (len != 8) {
		gnutls_assert();
		ret = GNUTLS_E_ILLEGAL_PARAMETER;
		goto error;
	}

	enc_params->cipher = GNUTLS_CIPHER_DES_CBC;

	ret = 0;
 error:
	asn1_delete_structure2(&pasn, ASN1_DELETE_FLAG_ZEROIZE);
	return ret;

}
コード例 #18
0
ファイル: privkey_pkcs8.c プロジェクト: gnutls/gnutls
/* Converts a GOST key to
 * an internal structure (gnutls_private_key)
 */
static int
_privkey_decode_gost_key(const gnutls_datum_t * raw_key,
			 gnutls_x509_privkey_t pkey)
{
	int ret;
	int ecc_size = gnutls_ecc_curve_get_size(pkey->params.curve);

	/* Just to be sure here */
	if (ecc_size <= 0) {
		gnutls_assert();
		ret = GNUTLS_E_ECC_UNSUPPORTED_CURVE;
		goto error;
	}

	/* Private key form described in R 50.1.112-2016.
	 * Private key can come up as masked value concatenated with several masks.
	 * each part is of ecc_size bytes. Key will be unmasked in pk_fixup */
	if (raw_key->size % ecc_size == 0) {
		ret = _gnutls_mpi_init_scan_le(&pkey->params.params[GOST_K],
				raw_key->data, raw_key->size);
		if (ret < 0) {
			gnutls_assert();
			goto error;
		}
	} else if (raw_key->data[0] == ASN1_TAG_INTEGER) {
		ASN1_TYPE pkey_asn;

		/* Very old format: INTEGER packed in OCTET STRING */
		if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
					       "GNUTLS.GOSTPrivateKeyOld",
					       &pkey_asn)) != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto error;
		}

		ret = _asn1_strict_der_decode(&pkey_asn,
				raw_key->data, raw_key->size,
				NULL);
		if (ret != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}

		ret = _gnutls_x509_read_key_int(pkey_asn, "",
						&pkey->params.params[GOST_K]);
		if (ret < 0) {
			gnutls_assert();
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}
		asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
	} else if (raw_key->data[0] == ASN1_TAG_OCTET_STRING) {
		ASN1_TYPE pkey_asn;

		/* format: OCTET STRING packed in OCTET STRING */
		if ((ret = asn1_create_element(_gnutls_get_gnutls_asn(),
					       "GNUTLS.GOSTPrivateKey",
					       &pkey_asn)) != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			goto error;
		}

		ret = _asn1_strict_der_decode(&pkey_asn,
				raw_key->data, raw_key->size,
				NULL);
		if (ret != ASN1_SUCCESS) {
			gnutls_assert();
			ret = _gnutls_asn2err(ret);
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}

		ret = _gnutls_x509_read_key_int_le(pkey_asn, "",
						   &pkey->params.params[GOST_K]);
		if (ret < 0) {
			gnutls_assert();
			asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
			goto error;
		}
		asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
	} else {
		gnutls_assert();
		ret = GNUTLS_E_PARSING_ERROR;
		goto error;
	}

	pkey->params.params_nr++;

	return 0;

      error:
	return ret;

}
コード例 #19
0
ファイル: privkey.c プロジェクト: Drakey83/steamlink-sdk
/* Converts an RSA PKCS#1 key to
 * an internal structure (gnutls_private_key)
 */
ASN1_TYPE
_gnutls_privkey_decode_pkcs1_rsa_key(const gnutls_datum_t * raw_key,
				     gnutls_x509_privkey_t pkey)
{
	int result;
	ASN1_TYPE pkey_asn;

	gnutls_pk_params_init(&pkey->params);

	pkey->params.algo = GNUTLS_PK_RSA;

	if ((result =
	     asn1_create_element(_gnutls_get_gnutls_asn(),
				 "GNUTLS.RSAPrivateKey",
				 &pkey_asn)) != ASN1_SUCCESS) {
		gnutls_assert();
		return NULL;
	}

	result =
	    asn1_der_decoding(&pkey_asn, raw_key->data, raw_key->size,
			      NULL);
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		goto error;
	}

	if ((result = _gnutls_x509_read_int(pkey_asn, "modulus",
					    &pkey->params.params[0])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result =
	     _gnutls_x509_read_int(pkey_asn, "publicExponent",
				   &pkey->params.params[1])) < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result =
	     _gnutls_x509_read_key_int(pkey_asn, "privateExponent",
				   &pkey->params.params[2])) < 0) {
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result = _gnutls_x509_read_key_int(pkey_asn, "prime1",
					    &pkey->params.params[3])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result = _gnutls_x509_read_key_int(pkey_asn, "prime2",
					    &pkey->params.params[4])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result = _gnutls_x509_read_key_int(pkey_asn, "coefficient",
					    &pkey->params.params[5])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result = _gnutls_x509_read_key_int(pkey_asn, "exponent1",
					    &pkey->params.params[6])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	if ((result = _gnutls_x509_read_key_int(pkey_asn, "exponent2",
					    &pkey->params.params[7])) < 0)
	{
		gnutls_assert();
		goto error;
	}
	pkey->params.params_nr++;

	result =
	    _gnutls_pk_fixup(GNUTLS_PK_RSA, GNUTLS_IMPORT, &pkey->params);
	if (result < 0) {
		gnutls_assert();
		goto error;
	}

	pkey->params.params_nr = RSA_PRIVATE_PARAMS;

	return pkey_asn;

      error:
	asn1_delete_structure2(&pkey_asn, ASN1_DELETE_FLAG_ZEROIZE);
	gnutls_pk_params_clear(&pkey->params);
	gnutls_pk_params_release(&pkey->params);
	return NULL;

}