/** * gnutls_x509_privkey_export: * @key: Holds the key * @format: the format of output params. One of PEM or DER. * @output_data: will contain a private key PEM or DER encoded * @output_data_size: holds the size of output_data (and will be * replaced by the actual size of parameters) * * This function will export the private key to a PKCS1 structure for * RSA keys, or an integer sequence for DSA keys. The DSA keys are in * the same format with the parameters used by openssl. * * If the buffer provided is not long enough to hold the output, then * *@output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER * will be returned. * * If the structure is PEM encoded, it will have a header * of "BEGIN RSA PRIVATE KEY". * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ int gnutls_x509_privkey_export (gnutls_x509_privkey_t key, gnutls_x509_crt_fmt_t format, void *output_data, size_t * output_data_size) { const char *msg; int ret; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } if (key->pk_algorithm == GNUTLS_PK_RSA) msg = PEM_KEY_RSA; else if (key->pk_algorithm == GNUTLS_PK_DSA) msg = PEM_KEY_DSA; else msg = NULL; if (key->crippled) { /* encode the parameters on the fly. */ switch (key->pk_algorithm) { case GNUTLS_PK_DSA: ret = _gnutls_asn1_encode_dsa (&key->key, key->params); if (ret < 0) { gnutls_assert (); return ret; } break; case GNUTLS_PK_RSA: ret = _gnutls_asn1_encode_rsa (&key->key, key->params); if (ret < 0) { gnutls_assert (); return ret; } break; default: gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } } return _gnutls_x509_export_int (key->key, format, msg, output_data, output_data_size); }
int _gnutls_asn1_encode_privkey(gnutls_pk_algorithm_t pk, ASN1_TYPE * c2, gnutls_pk_params_st * params) { switch (pk) { case GNUTLS_PK_RSA: return _gnutls_asn1_encode_rsa(c2, params); case GNUTLS_PK_DSA: return _gnutls_asn1_encode_dsa(c2, params); case GNUTLS_PK_EC: return _gnutls_asn1_encode_ecc(c2, params); default: return GNUTLS_E_UNIMPLEMENTED_FEATURE; } }
/** * gnutls_x509_privkey_cpy: * @dst: The destination key, which should be initialized. * @src: The source key * * This function will copy a private key from source to destination * key. Destination has to be initialized. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ int gnutls_x509_privkey_cpy (gnutls_x509_privkey_t dst, gnutls_x509_privkey_t src) { int i, ret; if (!src || !dst) return GNUTLS_E_INVALID_REQUEST; for (i = 0; i < src->params_size; i++) { dst->params[i] = _gnutls_mpi_copy (src->params[i]); if (dst->params[i] == NULL) return GNUTLS_E_MEMORY_ERROR; } dst->params_size = src->params_size; dst->pk_algorithm = src->pk_algorithm; dst->crippled = src->crippled; if (!src->crippled) { switch (dst->pk_algorithm) { case GNUTLS_PK_DSA: ret = _gnutls_asn1_encode_dsa (&dst->key, dst->params); if (ret < 0) { gnutls_assert (); return ret; } break; case GNUTLS_PK_RSA: ret = _gnutls_asn1_encode_rsa (&dst->key, dst->params); if (ret < 0) { gnutls_assert (); return ret; } break; default: gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } } return 0; }
/** * 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 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; } if (!key->crippled) asn1_delete_structure (&key->key); switch (key->pk_algorithm) { case GNUTLS_PK_DSA: ret = _gnutls_asn1_encode_dsa (&key->key, key->params); if (ret < 0) { gnutls_assert (); return ret; } break; case GNUTLS_PK_RSA: ret = _gnutls_asn1_encode_rsa (&key->key, key->params); if (ret < 0) { gnutls_assert (); return ret; } break; default: gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } return 0; }
/** * 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_generate: * @key: should contain a #gnutls_x509_privkey_t structure * @algo: is one of RSA or DSA. * @bits: the size of the modulus * @flags: unused for now. Must be 0. * * This function will generate a random private key. Note that this * function must be called on an empty private key. * * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits(). * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ int gnutls_x509_privkey_generate (gnutls_x509_privkey_t key, gnutls_pk_algorithm_t algo, unsigned int bits, unsigned int flags) { int ret; unsigned int params_len = MAX_PRIV_PARAMS_SIZE; unsigned int i; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } switch (algo) { case GNUTLS_PK_DSA: ret = _gnutls_dsa_generate_params (key->params, ¶ms_len, bits); if (params_len != DSA_PRIVATE_PARAMS) { gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; } if (ret < 0) { gnutls_assert (); return ret; } if (!key->crippled) { ret = _gnutls_asn1_encode_dsa (&key->key, key->params); if (ret < 0) { gnutls_assert (); goto cleanup; } } key->params_size = params_len; key->pk_algorithm = GNUTLS_PK_DSA; break; case GNUTLS_PK_RSA: ret = _gnutls_rsa_generate_params (key->params, ¶ms_len, bits); if (params_len != RSA_PRIVATE_PARAMS) { gnutls_assert (); ret = GNUTLS_E_INTERNAL_ERROR; } if (ret < 0) { gnutls_assert (); return ret; } if (!key->crippled) { ret = _gnutls_asn1_encode_rsa (&key->key, key->params); if (ret < 0) { gnutls_assert (); goto cleanup; } } key->params_size = params_len; key->pk_algorithm = GNUTLS_PK_RSA; break; default: gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } return 0; cleanup: key->pk_algorithm = GNUTLS_PK_UNKNOWN; key->params_size = 0; for (i = 0; i < params_len; i++) _gnutls_mpi_release (&key->params[i]); return ret; }