/* Writes the digest information and the digest in a DER encoded * structure. The digest info is allocated and stored into the info structure. */ static int encode_ber_digest_info (gnutls_digest_algorithm_t hash, const gnutls_datum_t * digest, gnutls_datum_t * info) { ASN1_TYPE dinfo = ASN1_TYPE_EMPTY; int result; const char *algo; algo = _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t) hash); if (algo == NULL) { gnutls_assert (); return GNUTLS_E_UNKNOWN_PK_ALGORITHM; } if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DigestInfo", &dinfo)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_write_value (dinfo, "digestAlgorithm.algorithm", algo, 1); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&dinfo); return _gnutls_asn2err (result); } result = asn1_write_value (dinfo, "digestAlgorithm.parameters", NULL, 0); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&dinfo); return _gnutls_asn2err (result); } result = asn1_write_value (dinfo, "digest", digest->data, digest->size); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&dinfo); return _gnutls_asn2err (result); } info->size = 0; asn1_der_coding (dinfo, "", NULL, &info->size, NULL); info->data = gnutls_malloc (info->size); if (info->data == NULL) { gnutls_assert (); asn1_delete_structure (&dinfo); return GNUTLS_E_MEMORY_ERROR; } result = asn1_der_coding (dinfo, "", info->data, &info->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&dinfo); return _gnutls_asn2err (result); } asn1_delete_structure (&dinfo); return 0; }
/* Writes the digest information and the digest in a DER encoded * structure. The digest info is allocated and stored into the info structure. */ static int encode_ber_digest_info (gnutls_digest_algorithm_t hash, const gnutls_datum_t * digest, gnutls_datum_t * info) { ASN1_TYPE dinfo = ASN1_TYPE_EMPTY; int result; const char *algo; algo = _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t) hash); if (algo == NULL) { gnutls_assert (); _gnutls_x509_log ("Hash algorithm: %d\n", hash); return GNUTLS_E_UNKNOWN_PK_ALGORITHM; } if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DigestInfo", &dinfo)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_write_value (dinfo, "digestAlgorithm.algorithm", algo, 1); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&dinfo); return _gnutls_asn2err (result); } /* Write an ASN.1 NULL in the parameters field. This matches RFC 3279 and RFC 4055, although is arguable incorrect from a historic perspective (see those documents for more information). Regardless of what is correct, this appears to be what most implementations do. */ result = asn1_write_value (dinfo, "digestAlgorithm.parameters", ASN1_NULL, ASN1_NULL_SIZE); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&dinfo); return _gnutls_asn2err (result); } result = asn1_write_value (dinfo, "digest", digest->data, digest->size); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&dinfo); return _gnutls_asn2err (result); } info->size = 0; asn1_der_coding (dinfo, "", NULL, &info->size, NULL); info->data = gnutls_malloc (info->size); if (info->data == NULL) { gnutls_assert (); asn1_delete_structure (&dinfo); return GNUTLS_E_MEMORY_ERROR; } result = asn1_der_coding (dinfo, "", info->data, &info->size, NULL); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&dinfo); return _gnutls_asn2err (result); } asn1_delete_structure (&dinfo); return 0; }
/* Create a DER-encoded value as a opaque signature when RSA is used. * See RFC 5246 DigitallySigned for the actual format. */ static int _gnutls_rsa_encode_sig (gnutls_mac_algorithm_t algo, const gnutls_datum_t * hash, gnutls_datum_t * signature) { ASN1_TYPE di; const char *oid; int result, signature_size; oid = _gnutls_x509_mac_to_oid (algo); if (!oid) { gnutls_assert (); return GNUTLS_E_UNKNOWN_HASH_ALGORITHM; } if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DigestInfo", &di)) != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } if ((result = asn1_write_value (di, "digestAlgorithm.algorithm", oid, strlen (oid))) != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&di); return _gnutls_asn2err (result); } /* Use NULL parameters. */ if ((result = asn1_write_value (di, "digestAlgorithm.parameters", ASN1_NULL, ASN1_NULL_SIZE)) != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&di); return _gnutls_asn2err (result); } if ((result = asn1_write_value (di, "digest", hash->data, hash->size)) != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&di); return _gnutls_asn2err (result); } signature_size = signature->size; result = asn1_der_coding (di, "", signature->data, &signature_size, NULL); asn1_delete_structure (&di); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } signature->size = signature_size; return 0; }