/** * 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_dsa_raw: * @key: The structure to store the parsed key * @p: holds the p * @q: holds the q * @g: holds the g * @y: holds the y * @x: holds the x * * This function will convert the given DSA 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_dsa_raw (gnutls_x509_privkey_t key, const gnutls_datum_t * p, const gnutls_datum_t * q, const gnutls_datum_t * g, const gnutls_datum_t * y, const gnutls_datum_t * x) { int i = 0, ret; size_t siz = 0; if (key == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } siz = p->size; if (_gnutls_mpi_scan_nz (&key->params[0], p->data, siz)) { gnutls_assert (); FREE_DSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } siz = q->size; if (_gnutls_mpi_scan_nz (&key->params[1], q->data, siz)) { gnutls_assert (); FREE_DSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } siz = g->size; if (_gnutls_mpi_scan_nz (&key->params[2], g->data, siz)) { gnutls_assert (); FREE_DSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } siz = y->size; if (_gnutls_mpi_scan_nz (&key->params[3], y->data, siz)) { gnutls_assert (); FREE_DSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } siz = x->size; if (_gnutls_mpi_scan_nz (&key->params[4], x->data, siz)) { gnutls_assert (); FREE_DSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } if (!key->crippled) { ret = _gnutls_asn1_encode_dsa (&key->key, key->params); if (ret < 0) { gnutls_assert (); FREE_DSA_PRIVATE_PARAMS; return ret; } } key->params_size = DSA_PRIVATE_PARAMS; key->pk_algorithm = GNUTLS_PK_DSA; 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; }