gnutls_x509_crt_fmt_t format, void *output_data,
size_t * output_data_size)
{
+ int ret;
+
if (pkcs12 == NULL) {
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
}
- return _gnutls_x509_export_int(pkcs12->pkcs12, format, PEM_PKCS12,
- output_data, output_data_size);
+ ret = _gnutls_x509_export_int(pkcs12->pkcs12, format, PEM_PKCS12,
+ output_data, output_data_size);
+
+ if (ret < 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ } else {
+ /* PKCS#12 export is always non-approved, because the MAC
+ * calculation involves non-approved KDF (PKCS#12 KDF) and
+ * without MAC the protection is insufficient.
+ */
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
+ }
+ return ret;
}
/**
gnutls_pkcs12_export2(gnutls_pkcs12_t pkcs12,
gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
{
+ int ret;
+
if (pkcs12 == NULL) {
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
}
- return _gnutls_x509_export_int2(pkcs12->pkcs12, format, PEM_PKCS12,
- out);
+ ret = _gnutls_x509_export_int2(pkcs12->pkcs12, format, PEM_PKCS12,
+ out);
+ if (ret < 0) {
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
+ } else {
+ /* PKCS#12 export is always non-approved, because the MAC
+ * calculation involves non-approved KDF (PKCS#12 KDF) and
+ * without MAC the protection is insufficient.
+ */
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
+ }
+ return ret;
}
static int oid2bag(const char *oid)
goto cleanup;
}
+ /* _gnutls_pkcs12_string_to_key is not a FIPS approved operation */
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
return 0;
cleanup:
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
_gnutls_free_datum(&tmp);
return result;
}
goto cleanup;
}
+ /* _gnutls_pkcs12_string_to_key is not a FIPS approved operation */
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED);
result = 0;
cleanup:
+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR);
_gnutls_free_datum(&tmp);
_gnutls_free_datum(&salt);
return result;
fprintf(stderr, "|<%d>| %s", level, str);
}
+#define FIPS_PUSH_CONTEXT() do { \
+ if (gnutls_fips140_mode_enabled()) { \
+ ret = gnutls_fips140_push_context(fips_context); \
+ if (ret < 0) { \
+ fail("gnutls_fips140_push_context failed\n"); \
+ } \
+ } \
+} while (0)
+
+#define FIPS_POP_CONTEXT(state) do { \
+ if (gnutls_fips140_mode_enabled()) { \
+ ret = gnutls_fips140_pop_context(); \
+ if (ret < 0) { \
+ fail("gnutls_fips140_context_pop failed\n"); \
+ } \
+ fips_state = gnutls_fips140_get_operation_state(fips_context); \
+ if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \
+ fail("operation state is not " # state " (%d)\n", \
+ fips_state); \
+ } \
+ } \
+} while (0)
+
void doit(void)
{
gnutls_pkcs12_t pkcs12;
char outbuf[10240];
size_t size;
unsigned tests, i;
+ gnutls_fips140_context_t fips_context;
+ gnutls_fips140_operation_state_t fips_state;
ret = global_init();
if (ret < 0) {
if (debug)
gnutls_global_set_log_level(4711);
+ ret = gnutls_fips140_context_init(&fips_context);
+ if (ret < 0) {
+ fail("Cannot initialize FIPS context\n");
+ }
+
/* Read certs. */
ret = gnutls_x509_crt_init(&client);
if (ret < 0) {
gnutls_pkcs12_bag_deinit(bag);
}
+ FIPS_PUSH_CONTEXT();
+
/* MAC the structure, export and print. */
ret = gnutls_pkcs12_generate_mac2(pkcs12, GNUTLS_MAC_SHA1, "pass");
if (ret < 0) {
exit(1);
}
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
+ FIPS_PUSH_CONTEXT();
+
ret = gnutls_pkcs12_verify_mac(pkcs12, "pass");
if (ret < 0) {
fprintf(stderr, "verify_mac: %s (%d)\n", gnutls_strerror(ret), ret);
exit(1);
}
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
+ FIPS_PUSH_CONTEXT();
+
ret = gnutls_pkcs12_generate_mac2(pkcs12, GNUTLS_MAC_SHA256, "passwd");
if (ret < 0) {
fprintf(stderr, "generate_mac2: %s (%d)\n", gnutls_strerror(ret), ret);
exit(1);
}
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
+ FIPS_PUSH_CONTEXT();
+
ret = gnutls_pkcs12_verify_mac(pkcs12, "passwd");
if (ret < 0) {
fprintf(stderr, "verify_mac2: %s (%d)\n", gnutls_strerror(ret), ret);
exit(1);
}
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
+ FIPS_PUSH_CONTEXT();
+
ret = gnutls_pkcs12_generate_mac2(pkcs12, GNUTLS_MAC_SHA512, "passwd1");
if (ret < 0) {
fprintf(stderr, "generate_mac2: %s (%d)\n", gnutls_strerror(ret), ret);
exit(1);
}
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
+ FIPS_PUSH_CONTEXT();
+
ret = gnutls_pkcs12_verify_mac(pkcs12, "passwd1");
if (ret < 0) {
fprintf(stderr, "verify_mac2: %s (%d)\n", gnutls_strerror(ret), ret);
exit(1);
}
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
+ FIPS_PUSH_CONTEXT();
+
size = sizeof(outbuf);
ret =
gnutls_pkcs12_export(pkcs12, GNUTLS_X509_FMT_PEM, outbuf,
exit(1);
}
+ FIPS_POP_CONTEXT(NOT_APPROVED);
+
if (debug)
fwrite(outbuf, size, 1, stdout);
/* Cleanup. */
+ gnutls_fips140_context_deinit(fips_context);
gnutls_pkcs12_deinit(pkcs12);
gnutls_x509_crt_deinit(client);
gnutls_x509_crt_deinit(ca);