return result;
}
- return dnssec_sign_verify(sign_ctx, &signature);
+ bool sign_cmp = dnssec_ctx->policy->reproducible_sign &&
+ dnssec_algorithm_allow_dsa_reproducible(
+ dnssec_ctx->policy->algorithm);
+
+ return dnssec_sign_verify(sign_ctx, sign_cmp, &signature);
}
goto fail;
}
- if (dnssec_sign_verify(sign_ctx, &signature) != KNOT_EOK) {
+ if (dnssec_sign_verify(sign_ctx, false, &signature) != KNOT_EOK) {
ret = KNOT_EINVAL;
goto fail;
}
-/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
*/
bool dnssec_algorithm_key_support(dnssec_key_algorithm_t algo);
+/*!
+ * Tell whether algo allows DSA deterministing signing.
+ */
+bool dnssec_algorithm_allow_dsa_reproducible(dnssec_key_algorithm_t algo);
+
/*!
* Allocate new DNSSEC key.
*
-/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+/* Copyright (C) 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
return algorithm_to_gnutls(algo) != GNUTLS_PK_UNKNOWN;
}
+_public_
+bool dnssec_algorithm_allow_dsa_reproducible(dnssec_key_algorithm_t algo)
+{
+#ifdef HAVE_GLNUTLS_REPRODUCIBLE
+ switch (algo) {
+ case DNSSEC_KEY_ALGORITHM_ECDSA_P256_SHA256:
+ case DNSSEC_KEY_ALGORITHM_ECDSA_P384_SHA384:
+ return true;
+ default:
+ return false;
+ }
+#else
+ return false;
+#endif
+}
+
_public_
int dnssec_algorithm_key_size_range(dnssec_key_algorithm_t algorithm,
unsigned *min_ptr, unsigned *max_ptr)
*
* \return Error code, DNSSEC_EOK if successful.
*/
-int dnssec_sign_write(dnssec_sign_ctx_t *ctx, dnssec_sign_flags_t flags, dnssec_binary_t *signature);
+int dnssec_sign_write(dnssec_sign_ctx_t *ctx, dnssec_sign_flags_t flags,
+ dnssec_binary_t *signature);
/*!
* Verify DNSSEC signature.
*
* \param ctx Signing context.
+ * \param sign_cmp Verify by signing and comparing signatures.
+ * Not possible for non-deterministic algorithms!
* \param signature Signature to be verified.
*
* \return Error code.
* \retval DNSSEC_EOK Validation successful, valid signature.
* \retval DNSSEC_INVALID_SIGNATURE Validation successful, invalid signature.
*/
-int dnssec_sign_verify(dnssec_sign_ctx_t *ctx, const dnssec_binary_t *signature);
+int dnssec_sign_verify(dnssec_sign_ctx_t *ctx, bool sign_cmp,
+ const dnssec_binary_t *signature);
/*! @} */
}
_public_
-int dnssec_sign_verify(dnssec_sign_ctx_t *ctx, const dnssec_binary_t *signature)
+int dnssec_sign_verify(dnssec_sign_ctx_t *ctx, bool sign_cmp, const dnssec_binary_t *signature)
{
if (!ctx || !signature) {
return DNSSEC_EINVAL;
}
+ if (sign_cmp && dnssec_key_can_sign(ctx->key)) {
+ dnssec_binary_t sign = { 0 };
+ int ret = dnssec_sign_write(ctx, DNSSEC_SIGN_REPRODUCIBLE, &sign);
+ if (ret == KNOT_EOK) {
+ ret = dnssec_binary_cmp(&sign, signature)
+ ? DNSSEC_INVALID_SIGNATURE
+ : DNSSEC_EOK;
+ }
+ return ret;
+ }
+
if (!dnssec_key_can_verify(ctx->key)) {
return DNSSEC_NO_PUBLIC_KEY;
}
t.link(zone, master, ixfr=True, journal_content="all")
master.dnssec(zone).enable = True
+master.dnssec(zone).repro_sign = True
t.start()
r = dnssec_sign_add(ctx, &input);
ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_add()");
- r = dnssec_sign_verify(ctx, &sign);
+ r = dnssec_sign_verify(ctx, false, &sign);
ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_verify()");
// software verification
r = dnssec_sign_add(ctx, &input);
ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_sign_add()");
- r = dnssec_sign_verify(ctx, &sign);
+ r = dnssec_sign_verify(ctx, false, &sign);
ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_sign_verify()");
dnssec_binary_free(&sign);
ok(r == DNSSEC_EOK, "create signing context");
r = dnssec_sign_add(ctx, data);
ok(r == DNSSEC_EOK, "add data to be signed");
- r = dnssec_sign_verify(ctx, signature);
+ r = dnssec_sign_verify(ctx, false, signature);
ok(r == DNSSEC_EOK, "signature verified");
// create new signature and self-validate
ok(r == DNSSEC_EOK, "write the signature");
ok(dnssec_binary_cmp(signature, &new_signature) == 0,
"signature exact match");
- r = dnssec_sign_verify(ctx, &new_signature);
+ r = dnssec_sign_verify(ctx, false, &new_signature);
ok(r == DNSSEC_EOK, "reverify the new signature");
dnssec_binary_free(&new_signature);
}
r = dnssec_sign_add(ctx, &tmp);
ok(r == DNSSEC_EOK, "add data (4)");
- r = dnssec_sign_verify(ctx, &new_signature);
+ r = dnssec_sign_verify(ctx, false, &new_signature);
ok(r == DNSSEC_EOK, "verify signature");
dnssec_binary_free(&new_signature);