/* 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); 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_int (pkey_asn, "privateExponent", &pkey->params.params[2])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "prime1", &pkey->params.params[3])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "prime2", &pkey->params.params[4])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient", &pkey->params.params[5])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_int (pkey_asn, "exponent1", &pkey->params.params[6])) < 0) { gnutls_assert (); goto error; } pkey->params.params_nr++; if ((result = _gnutls_x509_read_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_structure (&pkey_asn); gnutls_pk_params_release (&pkey->params); return NULL; }
/** * gnutls_x509_privkey_import_rsa_raw2: * @key: The structure to store the parsed key * @m: holds the modulus * @e: holds the public exponent * @d: holds the private exponent * @p: holds the first prime (p) * @q: holds the second prime (q) * @u: holds the coefficient * @e1: holds e1 = d mod (p-1) * @e2: holds e2 = d mod (q-1) * * This function will convert the given RSA raw parameters to the * native #gnutls_x509_privkey_t format. The output will be stored in * @key. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key, const gnutls_datum_t * m, const gnutls_datum_t * e, const gnutls_datum_t * d, const gnutls_datum_t * p, const gnutls_datum_t * q, const gnutls_datum_t * u, const gnutls_datum_t * e1, const gnutls_datum_t * e2) { int ret; size_t siz = 0; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } gnutls_pk_params_init(&key->params); siz = m->size; if (_gnutls_mpi_scan_nz (&key->params.params[0], m->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; siz = e->size; if (_gnutls_mpi_scan_nz (&key->params.params[1], e->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; siz = d->size; if (_gnutls_mpi_scan_nz (&key->params.params[2], d->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; siz = p->size; if (_gnutls_mpi_scan_nz (&key->params.params[3], p->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; siz = q->size; if (_gnutls_mpi_scan_nz (&key->params.params[4], q->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; siz = u->size; if (_gnutls_mpi_scan_nz (&key->params.params[5], u->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; if (e1 && e2) { siz = e1->size; if (_gnutls_mpi_scan_nz (&key->params.params[6], e1->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; siz = e2->size; if (_gnutls_mpi_scan_nz (&key->params.params[7], e2->data, siz)) { gnutls_assert (); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } key->params.params_nr++; } ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &key->params); if (ret < 0) { gnutls_assert (); goto cleanup; } ret = _gnutls_asn1_encode_privkey (GNUTLS_PK_RSA, &key->key, &key->params); if (ret < 0) { gnutls_assert (); goto cleanup; } key->params.params_nr = RSA_PRIVATE_PARAMS; key->pk_algorithm = GNUTLS_PK_RSA; return 0; cleanup: gnutls_pk_params_release(&key->params); return ret; }
/** * gnutls_x509_privkey_import_rsa_raw2: * @key: The structure to store the parsed key * @m: holds the modulus * @e: holds the public exponent * @d: holds the private exponent * @p: holds the first prime (p) * @q: holds the second prime (q) * @u: holds the coefficient * * This function will convert the given RSA raw parameters to the * native #gnutls_x509_privkey_t format. The output will be stored in * @key. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ int gnutls_x509_privkey_import_rsa_raw2 (gnutls_x509_privkey_t key, const gnutls_datum_t * m, const gnutls_datum_t * e, const gnutls_datum_t * d, const gnutls_datum_t * p, const gnutls_datum_t * q, const gnutls_datum_t * u, const gnutls_datum_t * e1, const gnutls_datum_t * e2) { int i = 0, ret; size_t siz = 0; gnutls_pk_params_st pk_params; memset (&pk_params, 0, sizeof (pk_params)); if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } key->params_size = 0; siz = m->size; if (_gnutls_mpi_scan_nz (&key->params[0], m->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } key->params_size++; siz = e->size; if (_gnutls_mpi_scan_nz (&key->params[1], e->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } key->params_size++; siz = d->size; if (_gnutls_mpi_scan_nz (&key->params[2], d->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } key->params_size++; siz = p->size; if (_gnutls_mpi_scan_nz (&key->params[3], p->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } key->params_size++; siz = q->size; if (_gnutls_mpi_scan_nz (&key->params[4], q->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } key->params_size++; siz = u->size; if (_gnutls_mpi_scan_nz (&key->params[5], u->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } key->params_size++; if (e1 && e2) { siz = e1->size; if (_gnutls_mpi_scan_nz (&key->params[6], e1->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } key->params_size++; siz = e2->size; if (_gnutls_mpi_scan_nz (&key->params[7], e2->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } key->params_size++; } for (i = 0; i < key->params_size; i++) { pk_params.params[i] = key->params[i]; } pk_params.params_nr = key->params_size; ret = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_IMPORT, &pk_params); if (ret < 0) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; return ret; } for (i = 0; i < pk_params.params_nr; i++) { key->params[i] = pk_params.params[i]; } key->params_size = pk_params.params_nr; if (!key->crippled) { ret = _gnutls_asn1_encode_rsa (&key->key, key->params); if (ret < 0) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; return ret; } } key->params_size = RSA_PRIVATE_PARAMS; key->pk_algorithm = GNUTLS_PK_RSA; return 0; }
/** * gnutls_x509_privkey_export_rsa_raw2: * @key: a structure that holds the rsa parameters * @m: will hold the modulus * @e: will hold the public exponent * @d: will hold the private exponent * @p: will hold the first prime (p) * @q: will hold the second prime (q) * @u: will hold the coefficient * @e1: will hold e1 = d mod (p-1) * @e2: will hold e2 = d mod (q-1) * * This function will export the RSA private key's parameters found * in the given structure. The new parameters will be allocated using * gnutls_malloc() and will be stored in the appropriate datum. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 2.12.0 **/ int gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key, gnutls_datum_t * m, gnutls_datum_t * e, gnutls_datum_t * d, gnutls_datum_t * p, gnutls_datum_t * q, gnutls_datum_t * u, gnutls_datum_t * e1, gnutls_datum_t * e2) { int ret; gnutls_pk_params_st pk_params; gnutls_pk_params_init(&pk_params); if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } m->data = e->data = d->data = p->data = q->data = u->data = NULL; m->size = e->size = d->size = p->size = q->size = u->size = 0; ret = _gnutls_pk_params_copy (&pk_params, &key->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 error; } ret = _gnutls_mpi_dprint_lz (pk_params.params[0], m); if (ret < 0) { gnutls_assert (); goto error; } /* E */ ret = _gnutls_mpi_dprint_lz (pk_params.params[1], e); if (ret < 0) { gnutls_assert (); goto error; } /* D */ ret = _gnutls_mpi_dprint_lz (pk_params.params[2], d); if (ret < 0) { gnutls_assert (); goto error; } /* P */ ret = _gnutls_mpi_dprint_lz (pk_params.params[3], p); if (ret < 0) { gnutls_assert (); goto error; } /* Q */ ret = _gnutls_mpi_dprint_lz (pk_params.params[4], q); if (ret < 0) { gnutls_assert (); goto error; } /* U */ ret = _gnutls_mpi_dprint_lz (key->params.params[5], u); if (ret < 0) { gnutls_assert (); goto error; } /* E1 */ if (e1) { ret = _gnutls_mpi_dprint_lz (key->params.params[6], e1); if (ret < 0) { gnutls_assert (); goto error; } } /* E2 */ if (e2) { ret = _gnutls_mpi_dprint_lz (key->params.params[7], e2); if (ret < 0) { gnutls_assert (); goto error; } } gnutls_pk_params_release (&pk_params); return 0; error: _gnutls_free_datum (m); _gnutls_free_datum (d); _gnutls_free_datum (e); _gnutls_free_datum (p); _gnutls_free_datum (q); gnutls_pk_params_release (&pk_params); return ret; }
/* Encodes the RSA parameters into an ASN.1 RSA private key structure. */ static int _gnutls_asn1_encode_rsa (ASN1_TYPE * c2, bigint_t * params) { int result; opaque null = '\0'; gnutls_pk_params_st pk_params; gnutls_datum_t m, e, d, p, q, u, exp1, exp2; memset (&pk_params, 0, sizeof (pk_params)); memset (&m, 0, sizeof (m)); memset (&p, 0, sizeof (e)); memset (&q, 0, sizeof (d)); memset (&p, 0, sizeof (p)); memset (&q, 0, sizeof (q)); memset (&u, 0, sizeof (u)); memset (&exp1, 0, sizeof (exp1)); memset (&exp2, 0, sizeof (exp2)); result = _gnutls_pk_params_copy (&pk_params, params, RSA_PRIVATE_PARAMS); if (result < 0) { gnutls_assert (); return result; } result = _gnutls_pk_fixup (GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params); if (result < 0) { gnutls_assert (); goto cleanup; } /* retrieve as data */ result = _gnutls_mpi_dprint_lz (pk_params.params[0], &m); if (result < 0) { gnutls_assert (); goto cleanup; } result = _gnutls_mpi_dprint_lz (pk_params.params[1], &e); if (result < 0) { gnutls_assert (); goto cleanup; } result = _gnutls_mpi_dprint_lz (pk_params.params[2], &d); if (result < 0) { gnutls_assert (); goto cleanup; } result = _gnutls_mpi_dprint_lz (pk_params.params[3], &p); if (result < 0) { gnutls_assert (); goto cleanup; } result = _gnutls_mpi_dprint_lz (pk_params.params[4], &q); if (result < 0) { gnutls_assert (); goto cleanup; } result = _gnutls_mpi_dprint_lz (pk_params.params[5], &u); if (result < 0) { gnutls_assert (); goto cleanup; } result = _gnutls_mpi_dprint_lz (pk_params.params[6], &exp1); if (result < 0) { gnutls_assert (); goto cleanup; } result = _gnutls_mpi_dprint_lz (pk_params.params[7], &exp2); if (result < 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 (); result = _gnutls_asn2err (result); goto cleanup; } /* Write PRIME */ if ((result = asn1_write_value (*c2, "modulus", m.data, m.size)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "publicExponent", e.data, e.size)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "privateExponent", d.data, d.size)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "prime1", p.data, p.size)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "prime2", q.data, q.size)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "coefficient", u.data, u.size)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "exponent1", exp1.data, exp1.size)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "exponent2", exp2.data, exp2.size)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "otherPrimeInfos", NULL, 0)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } result = 0; cleanup: if (result != 0) asn1_delete_structure (c2); gnutls_pk_params_release (&pk_params); _gnutls_free_datum (&m); _gnutls_free_datum (&d); _gnutls_free_datum (&e); _gnutls_free_datum (&p); _gnutls_free_datum (&q); _gnutls_free_datum (&u); _gnutls_free_datum (&exp1); _gnutls_free_datum (&exp2); return result; }
/* Extracts DSA and RSA parameters from a certificate. */ int _gnutls_openpgp_privkey_get_mpis(gnutls_openpgp_privkey_t pkey, uint32_t * keyid /*[2] */ , gnutls_pk_params_st * params) { int result; unsigned int i, pk_algorithm; cdk_packet_t pkt; unsigned total; gnutls_pk_params_init(params); if (keyid == NULL) pkt = cdk_kbnode_find_packet(pkey->knode, CDK_PKT_SECRET_KEY); else pkt = _gnutls_openpgp_find_key(pkey->knode, keyid, 1); if (pkt == NULL) { gnutls_assert(); return GNUTLS_E_OPENPGP_GETKEY_FAILED; } pk_algorithm = _gnutls_openpgp_get_algo(pkt->pkt.secret_key->pk->pubkey_algo); switch (pk_algorithm) { case GNUTLS_PK_RSA: /* openpgp does not hold all parameters as in PKCS #1 */ total = RSA_PRIVATE_PARAMS - 2; break; case GNUTLS_PK_DSA: total = DSA_PRIVATE_PARAMS; break; default: gnutls_assert(); return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; } for (i = 0; i < total; i++) { result = _gnutls_read_pgp_mpi(pkt, 1, i, ¶ms->params[i]); if (result < 0) { gnutls_assert(); goto error; } params->params_nr++; } /* fixup will generate exp1 and exp2 that are not * available here. */ result = _gnutls_pk_fixup(pk_algorithm, GNUTLS_IMPORT, params); if (result < 0) { gnutls_assert(); goto error; } return 0; error: gnutls_pk_params_clear(params); gnutls_pk_params_release(params); return result; }
/** * 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; }
/* 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; }
/* Extracts DSA and RSA parameters from a certificate. */ int _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey, uint32_t * keyid /*[2] */ , bigint_t * params, int *params_size) { int result, i; int pk_algorithm; gnutls_pk_params_st pk_params; cdk_packet_t pkt; memset (&pk_params, 0, sizeof (pk_params)); if (keyid == NULL) pkt = cdk_kbnode_find_packet (pkey->knode, CDK_PKT_SECRET_KEY); else pkt = _gnutls_openpgp_find_key (pkey->knode, keyid, 1); if (pkt == NULL) { gnutls_assert (); return GNUTLS_E_OPENPGP_GETKEY_FAILED; } pk_algorithm = _gnutls_openpgp_get_algo (pkt->pkt.secret_key->pk->pubkey_algo); switch (pk_algorithm) { case GNUTLS_PK_RSA: /* openpgp does not hold all parameters as in PKCS #1 */ pk_params.params_nr = RSA_PRIVATE_PARAMS - 2; break; case GNUTLS_PK_DSA: pk_params.params_nr = DSA_PRIVATE_PARAMS; break; default: gnutls_assert (); return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; } for (i = 0; i < pk_params.params_nr; i++) { result = _gnutls_read_pgp_mpi (pkt, 1, i, &pk_params.params[i]); if (result < 0) { gnutls_assert (); goto error; } } /* fixup will generate exp1 and exp2 that are not * available here. */ result = _gnutls_pk_fixup (pk_algorithm, GNUTLS_IMPORT, &pk_params); if (result < 0) { gnutls_assert (); goto error; } if (*params_size < pk_params.params_nr) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } *params_size = pk_params.params_nr; for (i = 0; i < pk_params.params_nr; i++) params[i] = pk_params.params[i]; return 0; error: { int j; for (j = 0; j < i; j++) _gnutls_mpi_release (&pk_params.params[j]); } return result; }