/* generate the proxyCertInfo in a DER encoded extension */ int _gnutls_x509_ext_gen_proxyCertInfo(int pathLenConstraint, const char *policyLanguage, const char *policy, size_t sizeof_policy, gnutls_datum_t * der_ext) { ASN1_TYPE ext = ASN1_TYPE_EMPTY; int result; result = asn1_create_element(_gnutls_get_pkix(), "PKIX1.ProxyCertInfo", &ext); if (result != ASN1_SUCCESS) { gnutls_assert(); return _gnutls_asn2err(result); } if (pathLenConstraint < 0) { result = asn1_write_value(ext, "pCPathLenConstraint", NULL, 0); if (result != ASN1_SUCCESS) result = _gnutls_asn2err(result); } else result = _gnutls_x509_write_uint32(ext, "pCPathLenConstraint", pathLenConstraint); if (result < 0) { gnutls_assert(); asn1_delete_structure(&ext); return result; } result = asn1_write_value(ext, "proxyPolicy.policyLanguage", policyLanguage, 1); if (result != ASN1_SUCCESS) { gnutls_assert(); asn1_delete_structure(&ext); return _gnutls_asn2err(result); } result = asn1_write_value(ext, "proxyPolicy.policy", policy, sizeof_policy); if (result != ASN1_SUCCESS) { gnutls_assert(); asn1_delete_structure(&ext); return _gnutls_asn2err(result); } result = _gnutls_x509_der_encode(ext, "", der_ext, 0); asn1_delete_structure(&ext); if (result < 0) { gnutls_assert(); return result; } return 0; }
/* generate the basicConstraints in a DER encoded extension * Use 0 or 1 (TRUE) for CA. * Use negative error codes for pathLenConstraint to indicate that the field * should not be present, >= 0 to indicate set values. */ int _gnutls_x509_ext_gen_basicConstraints (int CA, int pathLenConstraint, gnutls_datum_t * der_ext) { ASN1_TYPE ext = ASN1_TYPE_EMPTY; const char *str; int result; if (CA == 0) str = "FALSE"; else str = "TRUE"; result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext); if (result != ASN1_SUCCESS) { gnutls_assert (); return _gnutls_asn2err (result); } result = asn1_write_value (ext, "cA", str, 1); if (result != ASN1_SUCCESS) { gnutls_assert (); asn1_delete_structure (&ext); return _gnutls_asn2err (result); } if (pathLenConstraint < 0) { result = asn1_write_value (ext, "pathLenConstraint", NULL, 0); if (result < 0) result = _gnutls_asn2err (result); } else result = _gnutls_x509_write_uint32 (ext, "pathLenConstraint", pathLenConstraint); if (result < 0) { gnutls_assert (); asn1_delete_structure (&ext); return result; } result = _gnutls_x509_der_encode (ext, "", der_ext, 0); asn1_delete_structure (&ext); if (result < 0) { gnutls_assert (); return result; } return 0; }
/** * gnutls_pkcs12_generate_mac: * @pkcs12: should contain a gnutls_pkcs12_t structure * @pass: The password for the MAC * * This function will generate a MAC for the PKCS12 structure. * * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ int gnutls_pkcs12_generate_mac (gnutls_pkcs12_t pkcs12, const char *pass) { opaque salt[8], key[20]; int result; const int iter = 1; digest_hd_st td1; gnutls_datum_t tmp = { NULL, 0 }; opaque sha_mac[20]; if (pkcs12 == NULL) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } /* Generate the salt. */ result = _gnutls_rnd (GNUTLS_RND_NONCE, salt, sizeof (salt)); if (result < 0) { gnutls_assert (); return result; } /* Write the salt into the structure. */ result = asn1_write_value (pkcs12->pkcs12, "macData.macSalt", salt, sizeof (salt)); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } /* write the iterations */ if (iter > 1) { result = _gnutls_x509_write_uint32 (pkcs12->pkcs12, "macData.iterations", iter); if (result < 0) { gnutls_assert (); goto cleanup; } } /* Generate the key. */ result = _gnutls_pkcs12_string_to_key (3 /*MAC*/, salt, sizeof (salt), iter, pass, sizeof (key), key); if (result < 0) { gnutls_assert (); goto cleanup; } /* Get the data to be MACed */ result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, NULL, &tmp); if (result < 0) { gnutls_assert (); goto cleanup; } /* MAC the data */ result = _gnutls_hmac_init (&td1, GNUTLS_MAC_SHA1, key, sizeof (key)); if (result < 0) { gnutls_assert (); goto cleanup; } _gnutls_hmac (&td1, tmp.data, tmp.size); _gnutls_free_datum (&tmp); _gnutls_hmac_deinit (&td1, sha_mac); result = asn1_write_value (pkcs12->pkcs12, "macData.mac.digest", sha_mac, sizeof (sha_mac)); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } result = asn1_write_value (pkcs12->pkcs12, "macData.mac.digestAlgorithm.parameters", NULL, 0); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } result = asn1_write_value (pkcs12->pkcs12, "macData.mac.digestAlgorithm.algorithm", HASH_OID_SHA1, 1); if (result != ASN1_SUCCESS) { gnutls_assert (); result = _gnutls_asn2err (result); goto cleanup; } return 0; cleanup: _gnutls_free_datum (&tmp); return result; }
/** * gnutls_pkcs12_generate_mac2: * @pkcs12: A pkcs12 type * @mac: the MAC algorithm to use * @pass: The password for the MAC * * This function will generate a MAC for the PKCS12 structure. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. **/ int gnutls_pkcs12_generate_mac2(gnutls_pkcs12_t pkcs12, gnutls_mac_algorithm_t mac, const char *pass) { uint8_t salt[8], key[MAX_HASH_SIZE]; int result; const int iter = 10*1024; mac_hd_st td1; gnutls_datum_t tmp = { NULL, 0 }; unsigned mac_size, key_len; uint8_t mac_out[MAX_HASH_SIZE]; const mac_entry_st *me = mac_to_entry(mac); if (pkcs12 == NULL || me == NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); if (me->oid == NULL) return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); mac_size = _gnutls_mac_get_algo_len(me); key_len = mac_size; /* Generate the salt. */ result = gnutls_rnd(GNUTLS_RND_NONCE, salt, sizeof(salt)); if (result < 0) { gnutls_assert(); return result; } /* Write the salt into the structure. */ result = asn1_write_value(pkcs12->pkcs12, "macData.macSalt", salt, sizeof(salt)); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } /* write the iterations */ if (iter > 1) { result = _gnutls_x509_write_uint32(pkcs12->pkcs12, "macData.iterations", iter); if (result < 0) { gnutls_assert(); goto cleanup; } } /* Generate the key. */ #if ENABLE_GOST if (me->id == GNUTLS_MAC_GOSTR_94 || me->id == GNUTLS_MAC_STREEBOG_256 || me->id == GNUTLS_MAC_STREEBOG_512) { key_len = 32; result = _gnutls_pkcs12_gost_string_to_key(me->id, salt, sizeof(salt), iter, pass, mac_size, key); } else #endif result = _gnutls_pkcs12_string_to_key(me, 3 /*MAC*/, salt, sizeof(salt), iter, pass, mac_size, key); if (result < 0) { gnutls_assert(); goto cleanup; } /* Get the data to be MACed */ result = _decode_pkcs12_auth_safe(pkcs12->pkcs12, NULL, &tmp); if (result < 0) { gnutls_assert(); goto cleanup; } /* MAC the data */ result = _gnutls_mac_init(&td1, me, key, key_len); if (result < 0) { gnutls_assert(); goto cleanup; } _gnutls_mac(&td1, tmp.data, tmp.size); _gnutls_free_datum(&tmp); _gnutls_mac_deinit(&td1, mac_out); result = asn1_write_value(pkcs12->pkcs12, "macData.mac.digest", mac_out, mac_size); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } result = asn1_write_value(pkcs12->pkcs12, "macData.mac.digestAlgorithm.parameters", NULL, 0); if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } result = asn1_write_value(pkcs12->pkcs12, "macData.mac.digestAlgorithm.algorithm", me->oid, 1); if (result != ASN1_SUCCESS) { gnutls_assert(); result = _gnutls_asn2err(result); goto cleanup; } return 0; cleanup: _gnutls_free_datum(&tmp); return result; }
/** * gnutls_dh_params_export2_pkcs3: * @params: Holds the DH parameters * @format: the format of output params. One of PEM or DER. * @out: will contain a PKCS3 DHParams structure PEM or DER encoded * * This function will export the given dh parameters to a PKCS3 * DHParams structure. This is the format generated by "openssl dhparam" tool. * The data in @out will be allocated using gnutls_malloc(). * * If the structure is PEM encoded, it will have a header * of "BEGIN DH PARAMETERS". * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, * otherwise a negative error code is returned. * * Since: 3.1.3 **/ int gnutls_dh_params_export2_pkcs3(gnutls_dh_params_t params, gnutls_x509_crt_fmt_t format, gnutls_datum_t * out) { ASN1_TYPE c2; int result; size_t g_size, p_size; uint8_t *p_data, *g_data; uint8_t *all_data; _gnutls_mpi_print_lz(params->params[1], NULL, &g_size); _gnutls_mpi_print_lz(params->params[0], NULL, &p_size); all_data = gnutls_malloc(g_size + p_size); if (all_data == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } p_data = &all_data[0]; _gnutls_mpi_print_lz(params->params[0], p_data, &p_size); g_data = &all_data[p_size]; _gnutls_mpi_print_lz(params->params[1], g_data, &g_size); /* Ok. Now we have the data. Create the asn1 structures */ if ((result = asn1_create_element (_gnutls_get_gnutls_asn(), "GNUTLS.DHParameter", &c2)) != ASN1_SUCCESS) { gnutls_assert(); gnutls_free(all_data); return _gnutls_asn2err(result); } /* Write PRIME */ if ((result = asn1_write_value(c2, "prime", p_data, p_size)) != ASN1_SUCCESS) { gnutls_assert(); gnutls_free(all_data); asn1_delete_structure(&c2); return _gnutls_asn2err(result); } if (params->q_bits > 0) result = _gnutls_x509_write_uint32(c2, "privateValueLength", params->q_bits); else result = asn1_write_value(c2, "privateValueLength", NULL, 0); if (result < 0) { gnutls_assert(); gnutls_free(all_data); asn1_delete_structure(&c2); return _gnutls_asn2err(result); } /* Write the GENERATOR */ if ((result = asn1_write_value(c2, "base", g_data, g_size)) != ASN1_SUCCESS) { gnutls_assert(); gnutls_free(all_data); asn1_delete_structure(&c2); return _gnutls_asn2err(result); } gnutls_free(all_data); if (format == GNUTLS_X509_FMT_DER) { result = _gnutls_x509_der_encode(c2, "", out, 0); asn1_delete_structure(&c2); if (result < 0) return gnutls_assert_val(result); } else { /* PEM */ gnutls_datum_t t; result = _gnutls_x509_der_encode(c2, "", &t, 0); asn1_delete_structure(&c2); if (result < 0) return gnutls_assert_val(result); result = _gnutls_fbase64_encode("DH PARAMETERS", t.data, t.size, out); gnutls_free(t.data); if (result < 0) { gnutls_assert(); return result; } } return 0; }