/* * This function writes the parameters for DSS keys. * Needs 3 parameters (p,q,g). * * Allocates the space used to store the DER data. */ int _gnutls_x509_write_dsa_params (bigint_t * params, int params_size, gnutls_datum_t * der) { int result; ASN1_TYPE spk = ASN1_TYPE_EMPTY; der->data = NULL; der->size = 0; if (params_size < 3) { gnutls_assert (); result = GNUTLS_E_INVALID_REQUEST; goto cleanup; } if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAParameters", &spk)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = _gnutls_x509_write_int (spk, "p", params[0], 1); if (result < 0) { gnutls_assert (); goto cleanup; } result = _gnutls_x509_write_int (spk, "q", params[1], 1); if (result < 0) { gnutls_assert (); goto cleanup; } result = _gnutls_x509_write_int (spk, "g", params[2], 1); if (result < 0) { gnutls_assert (); goto cleanup; } result = _gnutls_x509_der_encode (spk, "", der, 0); if (result < 0) { gnutls_assert (); goto cleanup; } result = 0; cleanup: asn1_delete_structure (&spk); return result; }
/* * some x509 certificate functions that relate to MPI parameter * setting. This writes the BIT STRING subjectPublicKey. * Needs 2 parameters (m,e). * * Allocates the space used to store the DER data. */ static int _gnutls_x509_write_rsa_pubkey(gnutls_pk_params_st * params, gnutls_datum_t * der) { int result; ASN1_TYPE spk = ASN1_TYPE_EMPTY; der->data = NULL; der->size = 0; if (params->params_nr < RSA_PUBLIC_PARAMS) { gnutls_assert(); result = GNUTLS_E_INVALID_REQUEST; goto cleanup; } if ((result = asn1_create_element (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPublicKey", &spk)) != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } result = _gnutls_x509_write_int(spk, "modulus", params->params[0], 1); if (result < 0) { gnutls_assert(); goto cleanup; } result = _gnutls_x509_write_int(spk, "publicExponent", params->params[1], 1); if (result < 0) { gnutls_assert(); goto cleanup; } result = _gnutls_x509_der_encode(spk, "", der, 0); if (result < 0) { gnutls_assert(); goto cleanup; } result = 0; cleanup: asn1_delete_structure(&spk); return result; }
/* encodes the Dss-Sig-Value structure */ static int encode_ber_rs (gnutls_datum_t * sig_value, mpi_t r, mpi_t s) { ASN1_TYPE sig; int result, tot_len; if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSASignatureValue", &sig)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = _gnutls_x509_write_int (sig, "r", r, 1); if (result < 0) { gnutls_assert (); asn1_delete_structure (&sig); return result; } result = _gnutls_x509_write_int (sig, "s", s, 1); if (result < 0) { gnutls_assert (); asn1_delete_structure (&sig); return result; } tot_len = 0; result = _gnutls_x509_der_encode (sig, "", sig_value, 0); asn1_delete_structure (&sig); if (result < 0) { gnutls_assert (); return result; } return 0; }
/* 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; }
/* 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; }
/* 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; }