summaryrefslogtreecommitdiff
path: root/lib/x509/privkey_pkcs8.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/x509/privkey_pkcs8.c')
-rw-r--r--lib/x509/privkey_pkcs8.c522
1 files changed, 233 insertions, 289 deletions
diff --git a/lib/x509/privkey_pkcs8.c b/lib/x509/privkey_pkcs8.c
index 5ee1961c1e..91eb1f16c5 100644
--- a/lib/x509/privkey_pkcs8.c
+++ b/lib/x509/privkey_pkcs8.c
@@ -41,12 +41,11 @@
static int _decode_pkcs8_ecc_key(asn1_node pkcs8_asn,
gnutls_x509_privkey_t pkey);
-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);
+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);
-static int decode_private_key_info(const gnutls_datum_t * der,
+static int decode_private_key_info(const gnutls_datum_t *der,
gnutls_x509_privkey_t pkey);
#define PEM_PKCS8 "ENCRYPTED PRIVATE KEY"
@@ -59,8 +58,8 @@ static int decode_private_key_info(const gnutls_datum_t * der,
* 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)
+inline static int _encode_privkey(gnutls_x509_privkey_t pkey,
+ gnutls_datum_t *raw)
{
int ret;
asn1_node spk = NULL;
@@ -83,17 +82,16 @@ _encode_privkey(gnutls_x509_privkey_t pkey, gnutls_datum_t * raw)
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) {
+ 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]);
+ ret = _gnutls_x509_write_key_int_le(
+ spk, "", pkey->params.params[GOST_K]);
if (ret < 0) {
gnutls_assert();
goto error;
@@ -111,9 +109,8 @@ _encode_privkey(gnutls_x509_privkey_t pkey, gnutls_datum_t * raw)
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);
+ ret = _gnutls_x509_export_int2(pkey->key, GNUTLS_X509_FMT_DER,
+ "", raw);
if (ret < 0) {
gnutls_assert();
goto error;
@@ -122,15 +119,15 @@ _encode_privkey(gnutls_x509_privkey_t pkey, gnutls_datum_t * raw)
break;
case GNUTLS_PK_DSA:
/* DSAPublicKey == INTEGER */
- if ((ret = asn1_create_element
- (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey", &spk))
- != ASN1_SUCCESS) {
+ 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);
+ ret = _gnutls_x509_write_int(spk, "", pkey->params.params[4],
+ 1);
if (ret < 0) {
gnutls_assert();
goto error;
@@ -151,11 +148,10 @@ _encode_privkey(gnutls_x509_privkey_t pkey, gnutls_datum_t * raw)
return 0;
- error:
+error:
asn1_delete_structure2(&spk, ASN1_DELETE_FLAG_ZEROIZE);
asn1_delete_structure(&spk);
return ret;
-
}
/*
@@ -163,9 +159,8 @@ _encode_privkey(gnutls_x509_privkey_t pkey, gnutls_datum_t * raw)
* info. The output will be allocated and stored into der. Also
* the asn1_node of private key info will be returned.
*/
-static int
-encode_to_private_key_info(gnutls_x509_privkey_t pkey,
- gnutls_datum_t * der, asn1_node * pkey_info)
+static int encode_to_private_key_info(gnutls_x509_privkey_t pkey,
+ gnutls_datum_t *der, asn1_node *pkey_info)
{
int result, len;
uint8_t null = 0;
@@ -185,10 +180,9 @@ encode_to_private_key_info(gnutls_x509_privkey_t pkey,
return result;
}
- if ((result =
- asn1_create_element(_gnutls_get_pkix(),
- "PKIX1.pkcs-8-PrivateKeyInfo",
- pkey_info)) != ASN1_SUCCESS) {
+ if ((result = asn1_create_element(_gnutls_get_pkix(),
+ "PKIX1.pkcs-8-PrivateKeyInfo",
+ pkey_info)) != ASN1_SUCCESS) {
gnutls_assert();
result = _gnutls_asn2err(result);
goto error;
@@ -206,18 +200,16 @@ encode_to_private_key_info(gnutls_x509_privkey_t pkey,
/* write the privateKeyAlgorithm
* fields. (OID+NULL data)
*/
- result =
- asn1_write_value(*pkey_info, "privateKeyAlgorithm.algorithm",
- oid, 1);
+ 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);
+ result = asn1_write_value(*pkey_info, "privateKeyAlgorithm.parameters",
+ algo_params.data, algo_params.size);
_gnutls_free_key_datum(&algo_params);
if (result != ASN1_SUCCESS) {
@@ -234,9 +226,8 @@ encode_to_private_key_info(gnutls_x509_privkey_t pkey,
goto error;
}
- result =
- asn1_write_value(*pkey_info, "privateKey", algo_privkey.data,
- algo_privkey.size);
+ result = asn1_write_value(*pkey_info, "privateKey", algo_privkey.data,
+ algo_privkey.size);
_gnutls_free_key_datum(&algo_privkey);
if (result != ASN1_SUCCESS) {
@@ -245,8 +236,8 @@ encode_to_private_key_info(gnutls_x509_privkey_t pkey,
goto error;
}
- if ((pkey->params.pkflags & GNUTLS_PK_FLAG_PROVABLE)
- && pkey->params.seed_size > 0) {
+ if ((pkey->params.pkflags & GNUTLS_PK_FLAG_PROVABLE) &&
+ pkey->params.seed_size > 0) {
gnutls_datum_t seed_info;
/* rfc8479 attribute encoding */
@@ -256,9 +247,8 @@ encode_to_private_key_info(gnutls_x509_privkey_t pkey,
goto error;
}
- result =
- _x509_set_attribute(*pkey_info, "attributes",
- OID_ATTR_PROV_SEED, &seed_info);
+ result = _x509_set_attribute(*pkey_info, "attributes",
+ OID_ATTR_PROV_SEED, &seed_info);
gnutls_free(seed_info.data);
if (result < 0) {
gnutls_assert();
@@ -303,20 +293,18 @@ encode_to_private_key_info(gnutls_x509_privkey_t pkey,
return 0;
- error:
+error:
asn1_delete_structure2(pkey_info, ASN1_DELETE_FLAG_ZEROIZE);
_gnutls_free_datum(&algo_params);
_gnutls_free_key_datum(&algo_privkey);
return result;
-
}
/* 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_node * out)
+static int encode_to_pkcs8_key(schema_id schema, const gnutls_datum_t *der_key,
+ const char *password, asn1_node *out)
{
int result;
gnutls_datum_t key = { NULL, 0 };
@@ -331,19 +319,17 @@ encode_to_pkcs8_key(schema_id schema, const gnutls_datum_t * der_key,
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
}
- if ((result =
- asn1_create_element(_gnutls_get_pkix(),
- "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
- &pkcs8_asn)) != ASN1_SUCCESS) {
+ 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);
+ result = asn1_write_value(pkcs8_asn, "encryptionAlgorithm.algorithm",
+ s->write_oid, 1);
if (result != ASN1_SUCCESS) {
gnutls_assert();
@@ -354,18 +340,16 @@ encode_to_pkcs8_key(schema_id schema, const gnutls_datum_t * der_key,
/* Generate a symmetric key.
*/
- result =
- _gnutls_pkcs_generate_key(schema, password, &kdf_params,
- &enc_params, &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);
+ result = _gnutls_pkcs_write_schema_params(
+ schema, pkcs8_asn, "encryptionAlgorithm.parameters",
+ &kdf_params, &enc_params);
if (result < 0) {
gnutls_assert();
goto error;
@@ -375,7 +359,7 @@ encode_to_pkcs8_key(schema_id schema, const gnutls_datum_t * der_key,
* encrypt the Data.
*/
result =
- _gnutls_pkcs_raw_encrypt_data(der_key, &enc_params, &key, &tmp);
+ _gnutls_pkcs_raw_encrypt_data(der_key, &enc_params, &key, &tmp);
if (result < 0) {
gnutls_assert();
goto error;
@@ -383,8 +367,8 @@ encode_to_pkcs8_key(schema_id schema, const gnutls_datum_t * der_key,
/* write the encrypted data.
*/
- result =
- asn1_write_value(pkcs8_asn, "encryptedData", tmp.data, tmp.size);
+ result = asn1_write_value(pkcs8_asn, "encryptedData", tmp.data,
+ tmp.size);
if (result != ASN1_SUCCESS) {
gnutls_assert();
result = _gnutls_asn2err(result);
@@ -398,7 +382,7 @@ encode_to_pkcs8_key(schema_id schema, const gnutls_datum_t * der_key,
return 0;
- error:
+error:
_gnutls_free_key_datum(&key);
_gnutls_free_datum(&tmp);
asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
@@ -434,12 +418,11 @@ encode_to_pkcs8_key(schema_id schema, const gnutls_datum_t * der_key,
* Returns: In case of failure a negative error code will be
* returned, and 0 on success.
**/
-int
-gnutls_x509_privkey_export_pkcs8(gnutls_x509_privkey_t key,
- gnutls_x509_crt_fmt_t format,
- const char *password,
- unsigned int flags,
- void *output_data, size_t *output_data_size)
+int gnutls_x509_privkey_export_pkcs8(gnutls_x509_privkey_t key,
+ gnutls_x509_crt_fmt_t format,
+ const char *password, unsigned int flags,
+ void *output_data,
+ size_t *output_data_size)
{
asn1_node pkcs8_asn = NULL, pkey_info;
int ret;
@@ -462,18 +445,19 @@ gnutls_x509_privkey_export_pkcs8(gnutls_x509_privkey_t key,
schema = _gnutls_pkcs_flags_to_schema(flags);
- if (((flags & GNUTLS_PKCS_PLAIN) || password == NULL)
- && !(flags & GNUTLS_PKCS_NULL_PASSWORD)) {
+ if (((flags & GNUTLS_PKCS_PLAIN) || password == NULL) &&
+ !(flags & GNUTLS_PKCS_NULL_PASSWORD)) {
_gnutls_free_datum(&tmp);
- ret =
- _gnutls_x509_export_int(pkey_info, format,
- PEM_UNENCRYPTED_PKCS8,
- output_data, output_data_size);
+ ret = _gnutls_x509_export_int(pkey_info, format,
+ PEM_UNENCRYPTED_PKCS8,
+ output_data, output_data_size);
asn1_delete_structure2(&pkey_info, ASN1_DELETE_FLAG_ZEROIZE);
} else {
- asn1_delete_structure2(&pkey_info, ASN1_DELETE_FLAG_ZEROIZE); /* we don't need it */
+ 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);
@@ -483,9 +467,8 @@ gnutls_x509_privkey_export_pkcs8(gnutls_x509_privkey_t key,
return ret;
}
- ret =
- _gnutls_x509_export_int(pkcs8_asn, format, PEM_PKCS8,
- output_data, output_data_size);
+ ret = _gnutls_x509_export_int(pkcs8_asn, format, PEM_PKCS8,
+ output_data, output_data_size);
asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
}
@@ -517,11 +500,10 @@ gnutls_x509_privkey_export_pkcs8(gnutls_x509_privkey_t key,
*
* Since: 3.4.0
**/
-int
-gnutls_pkcs8_info(const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format,
- unsigned int *schema, unsigned int *cipher,
- void *salt, unsigned int *salt_size,
- unsigned int *iter_count, char **oid)
+int gnutls_pkcs8_info(const gnutls_datum_t *data, gnutls_x509_crt_fmt_t format,
+ unsigned int *schema, unsigned int *cipher, void *salt,
+ unsigned int *salt_size, unsigned int *iter_count,
+ char **oid)
{
int ret = 0, need_free = 0;
gnutls_datum_t _data;
@@ -541,15 +523,13 @@ gnutls_pkcs8_info(const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format,
if (format == GNUTLS_X509_FMT_PEM) {
/* Try the first header
*/
- ret =
- _gnutls_fbase64_decode(PEM_UNENCRYPTED_PKCS8,
- data->data, data->size, &_data);
+ ret = _gnutls_fbase64_decode(PEM_UNENCRYPTED_PKCS8, data->data,
+ data->size, &_data);
- if (ret < 0) { /* Try the encrypted header
+ if (ret < 0) { /* Try the encrypted header
*/
- ret =
- _gnutls_fbase64_decode(PEM_PKCS8, data->data,
- data->size, &_data);
+ ret = _gnutls_fbase64_decode(PEM_PKCS8, data->data,
+ data->size, &_data);
if (ret < 0) {
gnutls_assert();
@@ -597,7 +577,7 @@ gnutls_pkcs8_info(const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format,
return 0;
- cleanup:
+cleanup:
if (ret != GNUTLS_E_UNKNOWN_CIPHER_TYPE && oid) {
gnutls_free(*oid);
}
@@ -633,11 +613,10 @@ gnutls_pkcs8_info(const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format,
*
* 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)
+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_node pkcs8_asn = NULL, pkey_info;
int ret;
@@ -660,17 +639,18 @@ gnutls_x509_privkey_export2_pkcs8(gnutls_x509_privkey_t key,
schema = _gnutls_pkcs_flags_to_schema(flags);
- if (((flags & GNUTLS_PKCS_PLAIN) || password == NULL)
- && !(flags & GNUTLS_PKCS_NULL_PASSWORD)) {
+ 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);
+ 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 */
+ 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);
@@ -680,8 +660,8 @@ gnutls_x509_privkey_export2_pkcs8(gnutls_x509_privkey_t key,
return ret;
}
- ret =
- _gnutls_x509_export_int2(pkcs8_asn, format, PEM_PKCS8, out);
+ ret = _gnutls_x509_export_int2(pkcs8_asn, format, PEM_PKCS8,
+ out);
asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
}
@@ -689,28 +669,27 @@ gnutls_x509_privkey_export2_pkcs8(gnutls_x509_privkey_t key,
return ret;
}
- /* We've gotten this far. In the real world it's almost certain
+/* We've gotten this far. In the real world it's almost certain
* that we're dealing with a good file, but wrong password.
* Sadly like 90% of random data is somehow valid DER for the
* a first small number of bytes, so no easy way to guarantee. */
-#define CHECK_ERR_FOR_ENCRYPTED(result) \
- if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND || \
- result == GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND || \
- result == GNUTLS_E_ASN1_DER_ERROR || \
- result == GNUTLS_E_ASN1_VALUE_NOT_FOUND || \
- result == GNUTLS_E_ASN1_GENERIC_ERROR || \
- result == GNUTLS_E_ASN1_VALUE_NOT_VALID || \
- result == GNUTLS_E_ASN1_TAG_ERROR || \
- result == GNUTLS_E_ASN1_TAG_IMPLICIT || \
- result == GNUTLS_E_ASN1_TYPE_ANY_ERROR || \
- result == GNUTLS_E_ASN1_SYNTAX_ERROR || \
- result == GNUTLS_E_ASN1_DER_OVERFLOW) { \
- result = GNUTLS_E_DECRYPTION_FAILED; \
- }
-
-static int pkcs8_key_decrypt(const gnutls_datum_t * raw_key,
- asn1_node pkcs8_asn, const char *password,
- gnutls_x509_privkey_t pkey)
+#define CHECK_ERR_FOR_ENCRYPTED(result) \
+ if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND || \
+ result == GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND || \
+ result == GNUTLS_E_ASN1_DER_ERROR || \
+ result == GNUTLS_E_ASN1_VALUE_NOT_FOUND || \
+ result == GNUTLS_E_ASN1_GENERIC_ERROR || \
+ result == GNUTLS_E_ASN1_VALUE_NOT_VALID || \
+ result == GNUTLS_E_ASN1_TAG_ERROR || \
+ result == GNUTLS_E_ASN1_TAG_IMPLICIT || \
+ result == GNUTLS_E_ASN1_TYPE_ANY_ERROR || \
+ result == GNUTLS_E_ASN1_SYNTAX_ERROR || \
+ result == GNUTLS_E_ASN1_DER_OVERFLOW) { \
+ result = GNUTLS_E_DECRYPTION_FAILED; \
+ }
+
+static int pkcs8_key_decrypt(const gnutls_datum_t *raw_key, asn1_node pkcs8_asn,
+ const char *password, gnutls_x509_privkey_t pkey)
{
int result, len;
char enc_oid[MAX_OID_SIZE];
@@ -723,9 +702,8 @@ static int pkcs8_key_decrypt(const gnutls_datum_t * raw_key,
/* Check the encryption schema OID
*/
len = sizeof(enc_oid);
- result =
- asn1_read_value(pkcs8_asn, "encryptionAlgorithm.algorithm",
- enc_oid, &len);
+ result = asn1_read_value(pkcs8_asn, "encryptionAlgorithm.algorithm",
+ enc_oid, &len);
if (result != ASN1_SUCCESS) {
gnutls_assert();
goto error;
@@ -740,11 +718,10 @@ static int pkcs8_key_decrypt(const gnutls_datum_t * raw_key,
/* 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);
+ 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);
@@ -752,11 +729,10 @@ static int pkcs8_key_decrypt(const gnutls_datum_t * raw_key,
}
params_len = params_end - params_start + 1;
- result =
- _gnutls_read_pkcs_schema_params(&schema, password,
- &raw_key->data[params_start],
- params_len, &kdf_params,
- &enc_params);
+ result = _gnutls_read_pkcs_schema_params(&schema, password,
+ &raw_key->data[params_start],
+ params_len, &kdf_params,
+ &enc_params);
if (result < 0) {
gnutls_assert();
@@ -766,10 +742,9 @@ static int pkcs8_key_decrypt(const gnutls_datum_t * raw_key,
/* Parameters have been decoded. Now
* decrypt the EncryptedData.
*/
- result =
- _gnutls_pkcs_raw_decrypt_data(schema, pkcs8_asn, "encryptedData",
- password, &kdf_params, &enc_params,
- &tmp);
+ result = _gnutls_pkcs_raw_decrypt_data(schema, pkcs8_asn,
+ "encryptedData", password,
+ &kdf_params, &enc_params, &tmp);
if (result < 0) {
gnutls_assert();
result = GNUTLS_E_DECRYPTION_FAILED;
@@ -787,25 +762,24 @@ static int pkcs8_key_decrypt(const gnutls_datum_t * raw_key,
return 0;
- error:
+error:
return result;
}
-static int check_for_decrypted(const gnutls_datum_t * der)
+static int check_for_decrypted(const gnutls_datum_t *der)
{
int result;
asn1_node pkcs8_asn = NULL;
- if ((result =
- asn1_create_element(_gnutls_get_pkix(),
- "PKIX1.pkcs-8-PrivateKeyInfo",
- &pkcs8_asn)) != ASN1_SUCCESS) {
+ 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);
+ _asn1_strict_der_decode(&pkcs8_asn, der->data, der->size, NULL);
if (result != ASN1_SUCCESS) {
gnutls_assert();
result = _gnutls_asn2err(result);
@@ -813,16 +787,14 @@ static int check_for_decrypted(const gnutls_datum_t * der)
}
result = 0;
- error:
+error:
asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
return result;
-
}
-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)
+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];
@@ -837,18 +809,16 @@ int pkcs8_key_info(const gnutls_datum_t * 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) {
+ 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);
+ result = _asn1_strict_der_decode(&pkcs8_asn, raw_key->data,
+ raw_key->size, NULL);
if (result != ASN1_SUCCESS) {
gnutls_assert();
result = _gnutls_asn2err(result);
@@ -858,9 +828,8 @@ int pkcs8_key_info(const gnutls_datum_t * raw_key,
/* Check the encryption schema OID
*/
len = sizeof(enc_oid);
- result =
- asn1_read_value(pkcs8_asn, "encryptionAlgorithm.algorithm",
- enc_oid, &len);
+ result = asn1_read_value(pkcs8_asn, "encryptionAlgorithm.algorithm",
+ enc_oid, &len);
if (result != ASN1_SUCCESS) {
gnutls_assert();
goto error;
@@ -879,11 +848,10 @@ int pkcs8_key_info(const gnutls_datum_t * raw_key,
/* 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);
+ 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);
@@ -891,11 +859,10 @@ int pkcs8_key_info(const gnutls_datum_t * raw_key,
}
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);
+ result = _gnutls_read_pkcs_schema_params(&schema, NULL,
+ &raw_key->data[params_start],
+ params_len, kdf_params,
+ &enc_params);
if (result < 0) {
gnutls_assert();
@@ -917,7 +884,7 @@ int pkcs8_key_info(const gnutls_datum_t * raw_key,
result = 0;
- error:
+error:
asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
return result;
}
@@ -926,26 +893,22 @@ int pkcs8_key_info(const gnutls_datum_t * raw_key,
* 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)
+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_node pkcs8_asn = NULL;
- if ((result =
- asn1_create_element(_gnutls_get_pkix(),
- "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
- &pkcs8_asn)) != ASN1_SUCCESS) {
+ 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);
+ result = _asn1_strict_der_decode(&pkcs8_asn, raw_key->data,
+ raw_key->size, NULL);
if (result != ASN1_SUCCESS) {
gnutls_assert();
result = _gnutls_asn2err(result);
@@ -957,16 +920,15 @@ pkcs8_key_decode(const gnutls_datum_t * raw_key,
else
result = 0;
- error:
+error:
asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
return result;
-
}
/* Decodes an RSA privateKey from a PKCS8 structure.
*/
-static int
-_decode_pkcs8_rsa_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
+static int _decode_pkcs8_rsa_key(asn1_node pkcs8_asn,
+ gnutls_x509_privkey_t pkey)
{
int ret;
gnutls_datum_t tmp = { NULL, 0 };
@@ -988,14 +950,14 @@ _decode_pkcs8_rsa_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
ret = 0;
- error:
+error:
return ret;
}
/* Decodes an RSA-PSS privateKey from a PKCS8 structure.
*/
-static int
-_decode_pkcs8_rsa_pss_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
+static int _decode_pkcs8_rsa_pss_key(asn1_node pkcs8_asn,
+ gnutls_x509_privkey_t pkey)
{
int ret;
gnutls_datum_t tmp = { NULL, 0 };
@@ -1006,8 +968,8 @@ _decode_pkcs8_rsa_pss_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
ret = _gnutls_x509_read_value(pkcs8_asn,
"privateKeyAlgorithm.parameters", &tmp);
if (ret < 0) {
- if (ret == GNUTLS_E_ASN1_VALUE_NOT_FOUND
- || ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
+ if (ret == GNUTLS_E_ASN1_VALUE_NOT_FOUND ||
+ ret == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
goto skip_params;
gnutls_assert();
@@ -1022,7 +984,7 @@ _decode_pkcs8_rsa_pss_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
goto error;
}
- skip_params:
+skip_params:
ret = _decode_pkcs8_rsa_key(pkcs8_asn, pkey);
if (ret < 0) {
gnutls_assert();
@@ -1034,14 +996,14 @@ _decode_pkcs8_rsa_pss_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
ret = 0;
- error:
+error:
return ret;
}
/* Decodes an ECC privateKey from a PKCS8 structure.
*/
-static int
-_decode_pkcs8_ecc_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
+static int _decode_pkcs8_ecc_key(asn1_node pkcs8_asn,
+ gnutls_x509_privkey_t pkey)
{
int ret;
gnutls_datum_t tmp = { NULL, 0 };
@@ -1053,9 +1015,8 @@ _decode_pkcs8_ecc_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
* privateKeyAlgorithm.parameters instead of the ECPrivateKey.parameters.
*/
len = sizeof(oid);
- result =
- asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.parameters",
- oid, &len);
+ result = asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.parameters",
+ oid, &len);
if (result == ASN1_SUCCESS) {
ret = _gnutls_x509_read_ecc_params(oid, len, &curve);
if (ret < 0) {
@@ -1081,13 +1042,12 @@ _decode_pkcs8_ecc_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
ret = 0;
- error:
+error:
return ret;
}
-static int
-_decode_pkcs8_eddsa_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey,
- const char *oid)
+static int _decode_pkcs8_eddsa_key(asn1_node pkcs8_asn,
+ gnutls_x509_privkey_t pkey, const char *oid)
{
int ret;
gnutls_datum_t tmp;
@@ -1104,9 +1064,8 @@ _decode_pkcs8_eddsa_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey,
ce = _gnutls_ecc_curve_get_params(curve);
if (_curve_is_eddsa(ce)) {
- ret =
- _gnutls_x509_read_string(pkcs8_asn, "privateKey", &tmp,
- ASN1_ETYPE_OCTET_STRING, 1);
+ ret = _gnutls_x509_read_string(pkcs8_asn, "privateKey", &tmp,
+ ASN1_ETYPE_OCTET_STRING, 1);
if (ret < 0) {
gnutls_assert();
return gnutls_assert_val(ret);
@@ -1138,9 +1097,9 @@ _decode_pkcs8_eddsa_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey,
}
}
-static int
-_decode_pkcs8_modern_ecdh_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey,
- const char *oid)
+static int _decode_pkcs8_modern_ecdh_key(asn1_node pkcs8_asn,
+ gnutls_x509_privkey_t pkey,
+ const char *oid)
{
int ret;
gnutls_datum_t tmp;
@@ -1157,9 +1116,8 @@ _decode_pkcs8_modern_ecdh_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey,
ce = _gnutls_ecc_curve_get_params(curve);
if (_curve_is_modern_ecdh(ce)) {
- ret =
- _gnutls_x509_read_string(pkcs8_asn, "privateKey", &tmp,
- ASN1_ETYPE_OCTET_STRING, 1);
+ ret = _gnutls_x509_read_string(pkcs8_asn, "privateKey", &tmp,
+ ASN1_ETYPE_OCTET_STRING, 1);
if (ret < 0) {
gnutls_assert();
return gnutls_assert_val(ret);
@@ -1194,9 +1152,8 @@ _decode_pkcs8_modern_ecdh_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey,
/* 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)
+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);
@@ -1230,9 +1187,8 @@ _privkey_decode_gost_key(const gnutls_datum_t * raw_key,
goto error;
}
- ret = _asn1_strict_der_decode(&pkey_asn,
- raw_key->data, raw_key->size,
- NULL);
+ ret = _asn1_strict_der_decode(&pkey_asn, raw_key->data,
+ raw_key->size, NULL);
if (ret != ASN1_SUCCESS) {
gnutls_assert();
ret = _gnutls_asn2err(ret);
@@ -1262,9 +1218,8 @@ _privkey_decode_gost_key(const gnutls_datum_t * raw_key,
goto error;
}
- ret = _asn1_strict_der_decode(&pkey_asn,
- raw_key->data, raw_key->size,
- NULL);
+ ret = _asn1_strict_der_decode(&pkey_asn, raw_key->data,
+ raw_key->size, NULL);
if (ret != ASN1_SUCCESS) {
gnutls_assert();
ret = _gnutls_asn2err(ret);
@@ -1273,9 +1228,8 @@ _privkey_decode_gost_key(const gnutls_datum_t * raw_key,
goto error;
}
- ret = _gnutls_x509_read_key_int_le(pkey_asn, "",
- &pkey->
- params.params[GOST_K]);
+ ret = _gnutls_x509_read_key_int_le(
+ pkey_asn, "", &pkey->params.params[GOST_K]);
if (ret < 0) {
gnutls_assert();
asn1_delete_structure2(&pkey_asn,
@@ -1293,20 +1247,21 @@ _privkey_decode_gost_key(const gnutls_datum_t * raw_key,
return 0;
- error:
+error:
return ret;
-
}
/* Decodes a GOST privateKey from a PKCS8 structure.
*/
-static int
-_decode_pkcs8_gost_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey,
- gnutls_pk_algorithm_t algo)
+static int _decode_pkcs8_gost_key(asn1_node pkcs8_asn,
+ gnutls_x509_privkey_t pkey,
+ gnutls_pk_algorithm_t algo)
{
int ret;
gnutls_datum_t tmp;
- unsigned char oid[3 * MAX_OID_SIZE]; /* GOST parameters can have 3 OIDs at most */
+ unsigned char
+ oid[3 *
+ MAX_OID_SIZE]; /* GOST parameters can have 3 OIDs at most */
int len, result;
gnutls_pk_params_init(&pkey->params);
@@ -1319,9 +1274,8 @@ _decode_pkcs8_gost_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey,
ret = GNUTLS_E_PARSING_ERROR;
goto error;
} else {
- ret =
- _gnutls_x509_read_gost_params(oid, len, &pkey->params,
- algo);
+ ret = _gnutls_x509_read_gost_params(oid, len, &pkey->params,
+ algo);
if (ret < 0) {
gnutls_assert();
goto error;
@@ -1364,7 +1318,7 @@ _decode_pkcs8_gost_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey,
return 0;
- error:
+error:
gnutls_pk_params_clear(&pkey->params);
gnutls_pk_params_release(&pkey->params);
@@ -1373,8 +1327,8 @@ _decode_pkcs8_gost_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey,
/* Decodes an DSA privateKey and params from a PKCS8 structure.
*/
-static int
-_decode_pkcs8_dsa_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
+static int _decode_pkcs8_dsa_key(asn1_node pkcs8_asn,
+ gnutls_x509_privkey_t pkey)
{
int ret;
gnutls_datum_t tmp = { NULL, 0 };
@@ -1387,9 +1341,8 @@ _decode_pkcs8_dsa_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
goto error;
}
- ret =
- _gnutls_x509_read_der_int(tmp.data, tmp.size,
- &pkey->params.params[4]);
+ ret = _gnutls_x509_read_der_int(tmp.data, tmp.size,
+ &pkey->params.params[4]);
_gnutls_free_key_datum(&tmp);
if (ret < 0) {
@@ -1397,17 +1350,15 @@ _decode_pkcs8_dsa_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
goto error;
}
- ret =
- _gnutls_x509_read_value(pkcs8_asn,
- "privateKeyAlgorithm.parameters", &tmp);
+ ret = _gnutls_x509_read_value(pkcs8_asn,
+ "privateKeyAlgorithm.parameters", &tmp);
if (ret < 0) {
gnutls_assert();
goto error;
}
- ret =
- _gnutls_x509_read_pubkey_params(GNUTLS_PK_DSA, tmp.data,
- tmp.size, &pkey->params);
+ ret = _gnutls_x509_read_pubkey_params(GNUTLS_PK_DSA, tmp.data, tmp.size,
+ &pkey->params);
_gnutls_free_datum(&tmp);
if (ret < 0) {
gnutls_assert();
@@ -1445,14 +1396,14 @@ _decode_pkcs8_dsa_key(asn1_node pkcs8_asn, gnutls_x509_privkey_t pkey)
return 0;
- error:
+error:
if (pkey->params.params_nr != DSA_PRIVATE_PARAMS)
_gnutls_mpi_release(&pkey->params.params[4]);
return ret;
}
-static int
-decode_private_key_info(const gnutls_datum_t * der, gnutls_x509_privkey_t pkey)
+static int decode_private_key_info(const gnutls_datum_t *der,
+ gnutls_x509_privkey_t pkey)
{
int result, len;
char oid[MAX_OID_SIZE];
@@ -1460,17 +1411,16 @@ decode_private_key_info(const gnutls_datum_t * der, gnutls_x509_privkey_t pkey)
gnutls_datum_t sder;
int ret;
- if ((result =
- asn1_create_element(_gnutls_get_pkix(),
- "PKIX1.pkcs-8-PrivateKeyInfo",
- &pkcs8_asn)) != ASN1_SUCCESS) {
+ 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);
+ _asn1_strict_der_decode(&pkcs8_asn, der->data, der->size, NULL);
if (result != ASN1_SUCCESS) {
gnutls_assert();
result = _gnutls_asn2err(result);
@@ -1480,9 +1430,8 @@ decode_private_key_info(const gnutls_datum_t * der, gnutls_x509_privkey_t pkey)
/* Check the private key algorithm OID
*/
len = sizeof(oid);
- result =
- asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.algorithm",
- oid, &len);
+ result = asn1_read_value(pkcs8_asn, "privateKeyAlgorithm.algorithm",
+ oid, &len);
if (result != ASN1_SUCCESS) {
gnutls_assert();
result = _gnutls_asn2err(result);
@@ -1492,8 +1441,8 @@ decode_private_key_info(const gnutls_datum_t * der, gnutls_x509_privkey_t pkey)
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);
+ _gnutls_debug_log(
+ "PKCS #8 private key OID '%s' is unsupported.\n", oid);
result = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
goto error;
}
@@ -1525,8 +1474,8 @@ decode_private_key_info(const gnutls_datum_t * der, gnutls_x509_privkey_t pkey)
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);
+ result = _decode_pkcs8_gost_key(pkcs8_asn, pkey,
+ pkey->params.algo);
break;
default:
result = gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE);
@@ -1539,10 +1488,9 @@ decode_private_key_info(const gnutls_datum_t * der, gnutls_x509_privkey_t pkey)
}
/* 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_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) {
@@ -1552,10 +1500,9 @@ decode_private_key_info(const gnutls_datum_t * der, gnutls_x509_privkey_t pkey)
result = 0;
- error:
+error:
asn1_delete_structure2(&pkcs8_asn, ASN1_DELETE_FLAG_ZEROIZE);
return result;
-
}
/**
@@ -1586,11 +1533,10 @@ decode_private_key_info(const gnutls_datum_t * der, gnutls_x509_privkey_t pkey)
* 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 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;
@@ -1610,15 +1556,13 @@ gnutls_x509_privkey_import_pkcs8(gnutls_x509_privkey_t key,
if (format == GNUTLS_X509_FMT_PEM) {
/* Try the first header
*/
- result =
- _gnutls_fbase64_decode(PEM_UNENCRYPTED_PKCS8,
- data->data, data->size, &_data);
+ result = _gnutls_fbase64_decode(PEM_UNENCRYPTED_PKCS8,
+ data->data, data->size, &_data);
- if (result < 0) { /* Try the encrypted header
+ if (result < 0) { /* Try the encrypted header
*/
- result =
- _gnutls_fbase64_decode(PEM_PKCS8, data->data,
- data->size, &_data);
+ result = _gnutls_fbase64_decode(PEM_PKCS8, data->data,
+ data->size, &_data);
if (result < 0) {
gnutls_assert();
@@ -1641,11 +1585,11 @@ gnutls_x509_privkey_import_pkcs8(gnutls_x509_privkey_t key,
*/
if (flags & GNUTLS_PKCS_PLAIN) {
result = decode_private_key_info(&_data, key);
- if (result < 0) { /* check if it is encrypted */
+ if (result < 0) { /* check if it is encrypted */
if (pkcs8_key_decode(&_data, "", key, 0) == 0)
result = GNUTLS_E_DECRYPTION_FAILED;
}
- } else { /* encrypted. */
+ } else { /* encrypted. */
result = pkcs8_key_decode(&_data, password, key, 1);
}
@@ -1657,7 +1601,7 @@ gnutls_x509_privkey_import_pkcs8(gnutls_x509_privkey_t key,
/* 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);
+ _gnutls_pk_fixup(key->params.algo, GNUTLS_IMPORT, &key->params);
if (result < 0) {
gnutls_assert();
goto cleanup;
@@ -1670,7 +1614,7 @@ gnutls_x509_privkey_import_pkcs8(gnutls_x509_privkey_t key,
*/
return 0;
- cleanup:
+cleanup:
asn1_delete_structure2(&key->key, ASN1_DELETE_FLAG_ZEROIZE);
key->params.algo = GNUTLS_PK_UNKNOWN;
if (need_free) {