specified in RFC2459). This is now used when creating signatures too.
string representation of DSA signature algorithm fixed
added some 'const' values to function arguments
return LDNS_SIGNATURE_REMOVE_ADD_NEW;
}
+ldns_rdf *
+ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig,
+ const long sig_len)
+{
+ ldns_rdf *sigdata_rdf;
+ DSA_SIG *dsasig;
+ unsigned char *dsasig_data = ldns_buffer_begin(sig);
+
+ dsasig = d2i_DSA_SIG(NULL,
+ (const unsigned char **)&dsasig_data,
+ sig_len);
+ if (!dsasig) {
+ return NULL;
+ }
+
+ dsasig_data = LDNS_XMALLOC(unsigned char, 41);
+ dsasig_data[0] = 0;
+ BN_bn2bin(dsasig->r, &dsasig_data[1]);
+ BN_bn2bin(dsasig->s, &dsasig_data[21]);
+
+ sigdata_rdf = ldns_rdf_new(LDNS_RDF_TYPE_B64, 41, dsasig_data);
+ DSA_SIG_free(dsasig);
+
+ return sigdata_rdf;
+}
+
+ldns_status
+ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
+ const ldns_rdf *sig_rdf)
+{
+ /* the EVP api wants the DER encoding of the signature... */
+ uint8_t t;
+ BIGNUM *R, *S;
+ DSA_SIG *dsasig;
+ unsigned char *raw_sig = NULL;
+ int raw_sig_len;
+
+ /* extract the R and S field from the sig buffer */
+ t = ldns_rdf_data(sig_rdf)[0];
+ R = BN_new();
+ (void) BN_bin2bn(ldns_rdf_data(sig_rdf) + 1, SHA_DIGEST_LENGTH, R);
+ S = BN_new();
+ (void) BN_bin2bn(ldns_rdf_data(sig_rdf) + 21, SHA_DIGEST_LENGTH, S);
+
+ dsasig = DSA_SIG_new();
+ if (!dsasig) {
+ return LDNS_STATUS_MEM_ERR;
+ }
+
+ dsasig->r = R;
+ dsasig->s = S;
+
+ raw_sig_len = i2d_DSA_SIG(dsasig, &raw_sig);
+
+ if (ldns_buffer_reserve(target_buffer, raw_sig_len)) {
+ ldns_buffer_write(target_buffer, raw_sig, raw_sig_len);
+ }
+
+ DSA_SIG_free(dsasig);
+ free(raw_sig);
+
+ return ldns_buffer_status(target_buffer);
+}
+
+
+
#endif /* HAVE_SSL */
switch(ldns_key_algorithm(current_key)) {
case LDNS_SIGN_DSA:
case LDNS_DSA_NSEC3:
- b64rdf = ldns_sign_public_evp(sign_buf, ldns_key_evp_key(current_key), EVP_dss1());
- /* b64rdf = ldns_sign_public_dsa(sign_buf, ldns_key_dsa_key(current_key));*/
+ b64rdf = ldns_sign_public_evp(sign_buf,
+ ldns_key_evp_key(current_key),
+ EVP_dss1());
+ /*
+ b64rdf = ldns_sign_public_dsa(sign_buf, ldns_key_dsa_key(current_key));
+ */
break;
case LDNS_SIGN_RSASHA1:
case LDNS_SIGN_RSASHA1_NSEC3:
return sigdata_rdf;
}
+#ifdef HAVE_PKCS
+ldns_rdf *
+ldns_Sign_public_pkcs(ldns_Buffer *to_sign,
+ char *key_id,
+ const digest_type
+ )
+{
+
+}
+#endif
+
ldns_rdf *
ldns_sign_public_evp(ldns_buffer *to_sign,
EVP_PKEY *key,
EVP_MD_CTX_init(&ctx);
r = EVP_SignInit(&ctx, md_type);
- if(r == 1)
+ if(r == 1) {
r = EVP_SignUpdate(&ctx, (unsigned char*)
ldns_buffer_begin(to_sign),
ldns_buffer_position(to_sign));
- if(r == 1)
+ } else {
+ ldns_buffer_free(b64sig);
+ return NULL;
+ }
+ if(r == 1) {
r = EVP_SignFinal(&ctx, (unsigned char*)
ldns_buffer_begin(b64sig), &siglen, key);
+ } else {
+ ldns_buffer_free(b64sig);
+ return NULL;
+ }
if(r != 1) {
ldns_buffer_free(b64sig);
return NULL;
}
- sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
- ldns_buffer_begin(b64sig));
+ /* unfortunately, OpenSSL output is differenct from DNS DSA format */
+ if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
+ sigdata_rdf = ldns_convert_dsa_rrsig_asn12rdf(b64sig, siglen);
+ } else {
+ /* ok output for other types is the same */
+ sigdata_rdf = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, siglen,
+ ldns_buffer_begin(b64sig));
+ }
ldns_buffer_free(b64sig);
EVP_MD_CTX_cleanup(&ctx);
return sigdata_rdf;
}
/* create a buffer with b64 signature rdata */
- if (ldns_rdf2buffer_wire(rawsig_buf, ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
+ if (sig_algo == LDNS_DSA) {
+ if (ldns_convert_dsa_rrsig_rdf2asn1(rawsig_buf,
+ ldns_rr_rdf(rrsig, 8))
+ != LDNS_STATUS_OK) {
+ ldns_buffer_free(rawsig_buf);
+ ldns_buffer_free(verify_buf);
+ ldns_rr_list_deep_free(rrset_clone);
+ ldns_rr_list_deep_free(validkeys);
+ return LDNS_STATUS_MEM_ERR;
+ }
+ } else if (ldns_rdf2buffer_wire(rawsig_buf,
+ ldns_rr_rdf(rrsig, 8))
+ != LDNS_STATUS_OK) {
ldns_buffer_free(rawsig_buf);
ldns_buffer_free(verify_buf);
ldns_rr_list_deep_free(rrset_clone);
}
}
-ldns_status
-ldns_convert_dsa_rrsig_rdata(ldns_buffer *target_buffer,
- ldns_rdf *sig_rdf)
-{
- /* the EVP api wants the DER encoding of the signature... */
- uint8_t t;
- BIGNUM *R, *S;
- DSA_SIG *dsasig;
- unsigned char *raw_sig = NULL;
- int raw_sig_len;
-
- /* extract the R and S field from the sig buffer */
- t = ldns_rdf_data(sig_rdf)[0];
- R = BN_new();
- (void) BN_bin2bn(ldns_rdf_data(sig_rdf) + 1, SHA_DIGEST_LENGTH, R);
- S = BN_new();
- (void) BN_bin2bn(ldns_rdf_data(sig_rdf) + 21, SHA_DIGEST_LENGTH, S);
-
- dsasig = DSA_SIG_new();
- if (!dsasig) {
- return LDNS_STATUS_MEM_ERR;
- }
-
- dsasig->r = R;
- dsasig->s = S;
-
- raw_sig_len = i2d_DSA_SIG(dsasig, &raw_sig);
-
- if (ldns_buffer_reserve(target_buffer, raw_sig_len)) {
- ldns_buffer_write(target_buffer, raw_sig, raw_sig_len);
- }
-
- DSA_SIG_free(dsasig);
- free(raw_sig);
-
- return ldns_buffer_status(target_buffer);
-}
-
#if 0
void
print_dates(time_t now, time_t inception)
break;
case LDNS_DSA:
case LDNS_DSA_NSEC3:
- if (ldns_convert_dsa_rrsig_rdata(rawsig_buf,
- ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
- /*
- if (ldns_rdf2buffer_wire(rawsig_buf,
- ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
- */
+ /* EVP takes rfc2459 format, which is a tad longer than dns format */
+ exit(0);
+ if (ldns_convert_dsa_rrsig_rdf2asn1(rawsig_buf,
+ ldns_rr_rdf(rrsig, 8))
+ != LDNS_STATUS_OK) {
+ /*
+ if (ldns_rdf2buffer_wire(rawsig_buf,
+ ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
+ */
ldns_buffer_free(rawsig_buf);
ldns_buffer_free(verify_buf);
return LDNS_STATUS_MEM_ERR;
{ LDNS_SIGN_RSASHA1, "RSASHA1" },
{ LDNS_SIGN_RSASHA256, "RSASHA256" },
{ LDNS_SIGN_RSASHA512, "RSASHA512" },
- { LDNS_SIGN_DSA, "DSAMD5" },
+ { LDNS_SIGN_DSA, "DSA" },
{ LDNS_SIGN_HMACMD5, "hmac-md5.sig-alg.reg.int" },
{ 0, NULL }
};
memcpy(data, &T, 1);
if (T > 8) {
+ fprintf(stderr, "DSA key with T > 8 (ie. > 1024 bits)");
+ fprintf(stderr, " not implemented\n");
return false;
}
* \return the pointer to the data
*/
INLINE uint8_t *
-ldns_buffer_at(ldns_buffer *buffer, size_t at)
+ldns_buffer_at(const ldns_buffer *buffer, size_t at)
{
assert(at <= buffer->_limit);
return buffer->_data + at;
* \return the pointer
*/
INLINE uint8_t *
-ldns_buffer_begin(ldns_buffer *buffer)
+ldns_buffer_begin(const ldns_buffer *buffer)
{
return ldns_buffer_at(buffer, 0);
}
*/
int ldns_dnssec_default_replace_signatures(ldns_rr *sig, void *n);
+/**
+ * Converts the DSA signature from ASN1 representation (RFC2459, as
+ * used by OpenSSL) to raw signature data as used in DNS (rfc2536)
+ *
+ * \param[in] asn1_sig The signature in RFC2459 format
+ * \param[in] sig_len The length of the signature
+ * \return a new rdf with the signature
+ */
+ldns_rdf *
+ldns_convert_dsa_rrsig_asn12rdf(const ldns_buffer *sig,
+ const long sig_len);
+
+/**
+ * Converts the RRSIG signature RDF (in rfc2536 format) to a buffer
+ * with the signature in rfc2459 format
+ *
+ * \param[out] target_buffer, buffer to place the signature data
+ * \param[in] sig_rdf The signature rdf to convert
+ * \return LDNS_STATUS_OK on success, error code otherwise
+ */
+ldns_status
+ldns_convert_dsa_rrsig_rdf2asn1(ldns_buffer *target_buffer,
+ const ldns_rdf *sig_rdf);
+
+
#endif /* LDNS_DNSSEC_H */