/* reads the RSA public key from the given TSS key. * If psize is non-null it contains the total size of the parameters * in bytes */ static int read_pubkey(gnutls_pubkey_t pub, TSS_HKEY key_ctx, size_t * psize) { void *tdata; UINT32 tint; TSS_RESULT tssret; gnutls_datum_t m, e; int ret; /* read the public key */ tssret = Tspi_GetAttribData(key_ctx, TSS_TSPATTRIB_RSAKEY_INFO, TSS_TSPATTRIB_KEYINFO_RSA_MODULUS, &tint, (void *) &tdata); if (tssret != 0) { gnutls_assert(); return tss_err(tssret); } m.data = tdata; m.size = tint; tssret = Tspi_GetAttribData(key_ctx, TSS_TSPATTRIB_RSAKEY_INFO, TSS_TSPATTRIB_KEYINFO_RSA_EXPONENT, &tint, (void *) &tdata); if (tssret != 0) { gnutls_assert(); Tspi_Context_FreeMemory(key_ctx, m.data); return tss_err(tssret); } e.data = tdata; e.size = tint; ret = gnutls_pubkey_import_rsa_raw(pub, &m, &e); Tspi_Context_FreeMemory(key_ctx, m.data); Tspi_Context_FreeMemory(key_ctx, e.data); if (ret < 0) return gnutls_assert_val(ret); if (psize) *psize = e.size + m.size; return 0; }
static int dcrypt_gnutls_private_to_public_key(struct dcrypt_private_key *priv_key, struct dcrypt_public_key **pub_key_r, const char **error_r) { int ec; gnutls_privkey_t priv = (gnutls_privkey_t)priv_key; if (gnutls_privkey_get_pk_algorithm(priv, NULL) == GNUTLS_PK_RSA) { gnutls_datum_t m,e; /* do not extract anything we don't need */ ec = gnutls_privkey_export_rsa_raw(priv, &m, &e, NULL, NULL, NULL, NULL, NULL, NULL); if (ec != GNUTLS_E_SUCCESS) return dcrypt_gnutls_error(ec, error_r); gnutls_pubkey_t pub; gnutls_pubkey_init(&pub); ec = gnutls_pubkey_import_rsa_raw(pub, &m, &e); gnutls_free(m.data); gnutls_free(e.data); if (ec < 0) { gnutls_pubkey_deinit(pub); return dcrypt_gnutls_error(ec, error_r); } *pub_key_r = (struct dcrypt_public_key*)pub; return 0; } else if (gnutls_privkey_get_pk_algorithm(priv, NULL) == GNUTLS_PK_EC) { gnutls_ecc_curve_t curve; gnutls_datum_t x,y,k; ec = gnutls_privkey_export_ecc_raw(priv, &curve, &x, &y, NULL); if (ec != GNUTLS_E_SUCCESS) return dcrypt_gnutls_error(ec, error_r); gnutls_pubkey_t pub; gnutls_pubkey_init(&pub); ec = gnutls_pubkey_import_ecc_raw(pub, curve, &x, &y); gnutls_free(x.data); gnutls_free(y.data); if (ec < 0) { gnutls_pubkey_deinit(pub); return dcrypt_gnutls_error(ec, error_r); } *pub_key_r = (struct dcrypt_public_key*)pub; return 0; } return -1; }
static gnutls_pubkey_t create_rsa_from_modulus(unsigned char *modulus, unsigned int modulus_len, uint32_t exponent) { unsigned char exp_array[4]; uint32_t exponent_no = htonl(exponent); gnutls_pubkey_t rsa = NULL; gnutls_datum_t mod; gnutls_datum_t exp = { .data = exp_array, .size = sizeof(exp_array), }; int err; memcpy(exp_array, &exponent_no, sizeof(exp_array)); err = gnutls_pubkey_init(&rsa); if (err < 0) { fprintf(stderr, "Could not initialized public key structure : %s\n", gnutls_strerror(err)); return NULL; } mod.data = modulus; mod.size = modulus_len; err = gnutls_pubkey_import_rsa_raw(rsa, &mod, &exp); if (err < 0) { fprintf(stderr, "Could not set modulus and exponent on RSA key : %s\n", gnutls_strerror(err)); gnutls_pubkey_deinit(rsa); rsa = NULL; } return rsa; } static int asn_init() { static bool inited; int err; if (inited) return ASN1_SUCCESS; err = asn1_array2tree(tpm_asn1_tab, &_tpm_asn, NULL); if (err != ASN1_SUCCESS) { fprintf(stderr, "array2tree error: %d", err); goto cleanup; } inited = true; cleanup: return err; } static int create_tpm_manufacturer_info(const char *manufacturer, const char *tpm_model, const char *tpm_version, gnutls_datum_t *asn1) { ASN1_TYPE at = ASN1_TYPE_EMPTY; int err; err = asn_init(); if (err != ASN1_SUCCESS) { goto cleanup; } err = asn1_create_element(_tpm_asn, "TPM.TPMManufacturerInfo", &at); if (err != ASN1_SUCCESS) { fprintf(stderr, "asn1_create_element error: %d\n", err); goto cleanup; } err = asn1_write_value(at, "tpmManufacturer.id", "2.23.133.2.1", 0); if (err != ASN1_SUCCESS) { fprintf(stderr, "1. asn1_write_value error: %d\n", err); goto cleanup; } err = asn1_write_value(at, "tpmManufacturer.manufacturer", manufacturer, 0); if (err != ASN1_SUCCESS) { fprintf(stderr, "2. asn1_write_value error: %d\n", err); goto cleanup; } err = asn1_write_value(at, "tpmModel.id", "2.23.133.2.2", 0); if (err != ASN1_SUCCESS) { fprintf(stderr, "3. asn1_write_value error: %d\n", err); goto cleanup; } err = asn1_write_value(at, "tpmModel.model", manufacturer, 0); if (err != ASN1_SUCCESS) { fprintf(stderr, "4. asn1_write_value error: %d\n", err); goto cleanup; } err = asn1_write_value(at, "tpmVersion.id", "2.23.133.2.3", 0); if (err != ASN1_SUCCESS) { fprintf(stderr, "5. asn1_write_value error: %d\n", err); goto cleanup; } err = asn1_write_value(at, "tpmVersion.version", manufacturer, 0); if (err != ASN1_SUCCESS) { fprintf(stderr, "6. asn1_write_value error: %d\n", err); goto cleanup; } /* determine needed size of byte array */ asn1->size = 0; err = asn1_der_coding(at, "", NULL, (int *)&asn1->size, NULL); if (err != ASN1_MEM_ERROR) { fprintf(stderr, "1. asn1_der_coding error: %d\n", err); goto cleanup; } //fprintf(stderr, "size=%d\n", asn1->size); asn1->data = gnutls_malloc(asn1->size + 16); err = asn1_der_coding(at, "", asn1->data, (int *)&asn1->size, NULL); if (err != ASN1_SUCCESS) { fprintf(stderr, "2. asn1_der_coding error: %d\n", err); gnutls_free(asn1->data); asn1->data = NULL; goto cleanup; } #if 0 fprintf(stderr, "size=%d\n", asn1->size); unsigned int i = 0; for (i = 0; i < asn1->size; i++) { fprintf(stderr, "%02x ", asn1->data[i]); } fprintf(stderr, "\n"); #endif cleanup: asn1_delete_structure(&at); return err; }