# my own checks
AC_CHECK_PROG(doxygen, doxygen, doxygen)
+ACX_WITH_SSL_OPTIONAL
+
+# Use libtool
+ACX_LIBTOOL_C_ONLY
+
+# for macosx, see if glibtool exists and use that
+# BSD's need to know the version...
+#AC_CHECK_PROG(glibtool, glibtool, [glibtool], )
+#AC_CHECK_PROGS(libtool, [libtool15 libtool], [./libtool])
+
AC_ARG_ENABLE(sha2, AC_HELP_STRING([--enable-sha2], [Enable SHA256 and SHA512 RRSIG support]))
case "$enable_sha2" in
yes)
;;
esac
+AC_ARG_ENABLE(gost, AC_HELP_STRING([--enable-gost], [Enable GOST support]))
+case "$enable_gost" in
+ yes)
+ AC_MSG_CHECKING(for GOST)
+ AC_CHECK_LIB(crypto, ENGINE_load_gost,, [
+ AC_MSG_ERROR([GOST enabled, but no GOST functions found in OpenSSL. Need openssl-1.0.0 or later.])
+ ])
+ AC_DEFINE_UNQUOTED([USE_GOST], [1], [Define this to enable GOST support.])
+ ;;
+ no|*)
+ ;;
+esac
+
# add option to disable installation of ldns-config script
AC_ARG_ENABLE(ldns-config, [ --disable-ldns-config disable installation of ldns-config (default=enabled)],
enable_ldns_config=$enableval, enable_ldns_config=yes)
RPATH_VAL="-Wl,-rpath=\${libdir}"
fi
-ACX_WITH_SSL_OPTIONAL
-
-# Use libtool
-ACX_LIBTOOL_C_ONLY
-
-# for macosx, see if glibtool exists and use that
-# BSD's need to know the version...
-#AC_CHECK_PROG(glibtool, glibtool, [glibtool], )
-#AC_CHECK_PROGS(libtool, [libtool15 libtool], [./libtool])
-
#AC_TRY_RUN(
#[
#int main()
EVP_sha512());
break;
#endif /* USE_SHA2 */
+#ifdef USE_GOST
+ case LDNS_SIGN_GOST:
+ b64rdf = ldns_sign_public_evp(
+ sign_buf,
+ ldns_key_evp_key(current_key),
+ EVP_get_digestbyname("md_gost94"));
+ break;
+#endif /* USE_GOST */
case LDNS_SIGN_RSAMD5:
b64rdf = ldns_sign_public_evp(
sign_buf,
}
#endif /* HAVE_SSL */
+#ifdef USE_GOST
+static ldns_status
+ldns_verify_rrsig_gost_raw(unsigned char* sig, size_t siglen,
+ ldns_buffer* rrset, unsigned char* key, size_t keylen)
+{
+ EVP_PKEY *evp_key;
+ ldns_status result;
+ /* prefix header for X509 encoding */
+ uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
+ 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
+ 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
+ 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
+ unsigned char encoded[37+64];
+ const unsigned char* pp;
+ int i;
+ if(keylen != 64)
+ return LDNS_STATUS_CRYPTO_BOGUS;
+
+ /* create evp_key */
+ for(i=0; i<37; i++)
+ encoded[i] = asn[i];
+ for(i=0; i<64; i++)
+ encoded[i+37] = key[i];
+ pp = (unsigned char*)&encoded[0];
+ evp_key = d2i_PUBKEY(NULL, &pp, sizeof(encoded));
+
+ /* verify signature */
+ result = ldns_verify_rrsig_evp_raw(sig, siglen, rrset,
+ evp_key, EVP_get_digestbyname("md_gost94"));
+ EVP_PKEY_free(evp_key);
+
+ return result;
+}
+#endif
+
+
ldns_status
ldns_verify_rrsig_buffers(ldns_buffer *rawsig_buf, ldns_buffer *verify_buf,
ldns_buffer *key_buf, uint8_t algo)
key,
keylen);
break;
+#endif
+#ifdef USE_GOST
+ case LDNS_GOST:
+ return ldns_verify_rrsig_gost_raw(sig, siglen, verify_buf,
+ key, keylen);
+ break;
#endif
case LDNS_RSAMD5:
return ldns_verify_rrsig_rsamd5_raw(sig,
#ifdef USE_SHA2
case LDNS_RSASHA256:
case LDNS_RSASHA512:
+#endif
+#ifdef USE_GOST
+ case LDNS_GOST:
#endif
if (ldns_rdf2buffer_wire(rawsig_buf,
ldns_rr_rdf(rrsig, 8)) != LDNS_STATUS_OK) {
unsigned char* key,
size_t keylen)
{
-#ifdef USE_SHA2
- EVP_PKEY *evp_key;
+#ifdef use_sha2
+ evp_pkey *evp_key;
ldns_status result;
- evp_key = EVP_PKEY_new();
- EVP_PKEY_assign_RSA(evp_key, ldns_key_buf2rsa_raw(key, keylen));
+ evp_key = evp_pkey_new();
+ evp_pkey_assign_rsa(evp_key, ldns_key_buf2rsa_raw(key, keylen));
result = ldns_verify_rrsig_evp_raw(sig,
siglen,
rrset,
}
-
ldns_status
ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
size_t siglen,
;;
esac
-
+AC_ARG_ENABLE(gost, AC_HELP_STRING([--enable-gost], [Enable GOST support]))
+case "$enable_gost" in
+ yes)
+ AC_MSG_CHECKING(for GOST)
+ AC_CHECK_LIB(crypto, ENGINE_load_gost,, [
+ AC_MSG_ERROR([GOST enabled, but no GOST functions found in OpenSSL. Need openssl-1.0.0 or later.])
+ ])
+ AC_DEFINE_UNQUOTED([USE_GOST], [1], [Define this to enable GOST support.])
+ ;;
+ no|*)
+ ;;
+esac
#AC_CHECK_HEADER(ldns/ldns.h,, [
# AC_MSG_ERROR([Can't find ldns headers (make copy-headers in devel source.)])
}
#endif
+#if defined(HAVE_SSL) && defined(USE_GOST)
+static ldns_status
+ldns_gost_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
+{
+ unsigned char* pp = NULL;
+ int ret;
+ ldns_rdf *b64_bignum;
+ ldns_status status;
+
+ ret = i2d_PrivateKey(p, &pp);
+ b64_bignum = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_B64, ret, pp);
+ status = ldns_rdf2buffer_str(output, b64_bignum);
+
+ ldns_rdf_deep_free(b64_bignum);
+ OPENSSL_free(pp);
+ ldns_buffer_printf(output, "\n");
+ return LDNS_STATUS_OK;
+}
+#endif
+
ldns_status
ldns_key2buffer_str(ldns_buffer *output, const ldns_key *k)
{
printf("(Not available)\n");
}
break;
+ case LDNS_SIGN_GOST:
+ /* no format defined, use blob */
+#if defined(HAVE_SSL) && defined(USE_GOST)
+ ldns_buffer_printf(output, "Private-key-format: v1.2\n");
+ ldns_buffer_printf(output, "Algorithm: 11 (GOST)\n");
+ status = ldns_gost_key2buffer_str(output, k->_key.key);
+#endif
+ break;
case LDNS_SIGN_HMACMD5:
/* there's not much of a format defined for TSIG */
/* It's just a binary blob, Same for all algorithms */
#ifdef USE_SHA2
{ LDNS_SIGN_RSASHA256, "RSASHA256" },
{ LDNS_SIGN_RSASHA512, "RSASHA512" },
+#endif
+#ifdef USE_GOST
+ { LDNS_SIGN_GOST, "GOST" },
#endif
{ LDNS_SIGN_DSA, "DSA" },
{ LDNS_SIGN_DSA_NSEC3, "DSA_NSEC3" },
}
#endif
+#ifdef USE_GOST
+/** returns the PKEY id for GOST, loads GOST into openssl */
+static int
+ldns_get_EVP_gost_id()
+{
+ const EVP_PKEY_ASN1_METHOD* meth;
+ int gost_id;
+ ENGINE* e;
+
+ ENGINE_load_gost();
+ e = ENGINE_by_id("gost");
+ if(!e) {
+ /* no gost engine in openssl */
+ return 0;
+ }
+ if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
+ ENGINE_free(e);
+ return 0;
+ }
+
+ meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
+ ENGINE_free(e);
+ if(!meth) {
+ /* algo not found */
+ return 0;
+ }
+
+ EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
+ return gost_id;
+}
+
+/** read GOST private key */
+static EVP_PKEY*
+ldns_key_new_frm_fp_gost_l(FILE* fp, int* line_nr)
+{
+ ssize_t len;
+ char token[16384];
+ const unsigned char* pp;
+ int gost_id;
+ EVP_PKEY* pkey;
+ ldns_rdf* b64rdf = NULL;
+
+ gost_id = ldns_get_EVP_gost_id();
+ if(!gost_id)
+ return NULL;
+
+ len = ldns_fget_token_l(fp, token, "", sizeof(token), line_nr);
+ if(len == -1)
+ return NULL;
+ if(ldns_str2rdf_b64(&b64rdf, token) != LDNS_STATUS_OK)
+ return NULL;
+ pp = (unsigned char*)ldns_rdf_data(b64rdf);
+ pkey = d2i_PrivateKey(gost_id, NULL, &pp, ldns_rdf_size(b64rdf));
+ ldns_rdf_deep_free(b64rdf);
+ return pkey;
+}
+#endif
+
ldns_status
ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
{
#else
fprintf(stderr, "Warning: SHA512 not compiled into this ");
fprintf(stderr, "version of ldns\n");
+#endif
+ }
+ if (strncmp(d, "11 GOST", 3) == 0) {
+#ifdef USE_GOST
+ alg = LDNS_SIGN_GOST;
+#else
+ fprintf(stderr, "Warning: GOST not compiled into this ");
+ fprintf(stderr, "version of ldns\n");
#endif
}
if (strncmp(d, "157 HMAC-MD5", 4) == 0) {
ldns_key_set_hmac_key(k, hmac);
#endif /* HAVE_SSL */
break;
+ case LDNS_SIGN_GOST:
+ ldns_key_set_algorithm(k, alg);
+#if defined(HAVE_SSL) && defined(USE_GOST)
+ ldns_key_set_evp_key(k,
+ ldns_key_new_frm_fp_gost_l(fp, line_nr));
+ if(!k->_key.key)
+ return LDNS_STATUS_ERR;
+#endif
+ break;
case 0:
default:
return LDNS_STATUS_SYNTAX_ALG_ERR;
ldns_key_set_flags(k, 0);
break;
+ case LDNS_SIGN_GOST:
+#if defined(HAVE_SSL) && defined(USE_GOST)
+ if(1) { /* new stack context */
+ EVP_PKEY_CTX* ctx;
+ EVP_PKEY* p = NULL;
+ int gost_id = ldns_get_EVP_gost_id();
+ if(!gost_id)
+ return NULL;
+ ctx = EVP_PKEY_CTX_new_id(gost_id, NULL);
+ if(!ctx) {
+ /* the id should be available now */
+ return NULL;
+ }
+ if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) {
+ /* cannot set paramset */
+ EVP_PKEY_CTX_free(ctx);
+ return NULL;
+ }
+
+ if(EVP_PKEY_keygen_init(ctx) <= 0) {
+ EVP_PKEY_CTX_free(ctx);
+ return NULL;
+ }
+ if(EVP_PKEY_keygen(ctx, &p) <= 0) {
+ EVP_PKEY_free(p);
+ EVP_PKEY_CTX_free(ctx);
+ return NULL;
+ }
+ EVP_PKEY_CTX_free(ctx);
+ ldns_key_set_evp_key(k, p);
+ }
+#endif /* HAVE_SSL and USE_GOST */
+ break;
}
ldns_key_set_algorithm(k, alg);
return k;
*size = 21 + (*size * 3);
return true;
}
+
+static bool
+ldns_key_gost2bin(unsigned char* data, EVP_PKEY* k, uint16_t* size)
+{
+ int i;
+ unsigned char* pp = NULL;
+ if(i2d_PUBKEY(k, &pp) != 37 + 64) {
+ /* expect 37 byte(ASN header) and 64 byte(X and Y) */
+ CRYPTO_free(pp);
+ return false;
+ }
+ /* omit ASN header */
+ for(i=0; i<64; i++)
+ data[i] = pp[i+37];
+ CRYPTO_free(pp);
+ *size = 64;
+ return true;
+}
#endif /* HAVE_SSL */
ldns_rr *
}
#endif /* HAVE_SSL */
break;
+ case LDNS_SIGN_GOST:
+ ldns_rr_push_rdf(pubkey, ldns_native2rdf_int8(
+ LDNS_RDF_TYPE_ALG, ldns_key_algorithm(k)));
+#if defined(HAVE_SSL) && defined(USE_GOST)
+ bin = LDNS_XMALLOC(unsigned char, LDNS_MAX_KEYLEN);
+ if (!bin)
+ return NULL;
+ if (!ldns_key_gost2bin(bin, k->_key.key, &size)) {
+ return NULL;
+ }
+ internal_data = 1;
+ break;
+#endif /* HAVE_SSL and USE_GOST */
case LDNS_SIGN_HMACMD5:
case LDNS_SIGN_HMACSHA1:
case LDNS_SIGN_HMACSHA256:
LDNS_RSASHA1_NSEC3 = 7,
LDNS_RSASHA256 = 8, /* not official */
LDNS_RSASHA512 = 10, /* not official */
+ LDNS_GOST = 11, /* not official */
LDNS_INDIRECT = 252,
LDNS_PRIVATEDNS = 253,
LDNS_PRIVATEOID = 254
enum ldns_enum_hash
{
LDNS_SHA1 = 1,
- LDNS_SHA256 = 2
+ LDNS_SHA256 = 2,
+ LDNS_GOST34_11_94 = 3 /* not official */
};
typedef enum ldns_enum_hash ldns_hash;
LDNS_SIGN_RSASHA256 = LDNS_RSASHA256,
LDNS_SIGN_RSASHA512 = LDNS_RSASHA512,
LDNS_SIGN_DSA_NSEC3 = LDNS_DSA_NSEC3,
+ LDNS_SIGN_GOST = LDNS_GOST,
LDNS_SIGN_HMACMD5 = 157, /* not official! This type is for TSIG, not DNSSEC */
LDNS_SIGN_HMACSHA1 = 158, /* not official! This type is for TSIG, not DNSSEC */
LDNS_SIGN_HMACSHA256 = 159 /* ditto */
rd);
/* check if the origin should be used or concatenated */
- if (rd_strlen == 1 && ldns_rdf_data(r)[1] == '@') {
+ if (ldns_rdf_size(r) > 0 && ldns_rdf_data(r)[0] == 1
+ && ldns_rdf_data(r)[1] == '@') {
ldns_rdf_deep_free(r);
if (origin) {
r = ldns_rdf_clone(origin);
return 0;
}
break;
+#ifdef USE_GOST
+ case LDNS_SIGN_GOST:
+ return 512;
+ break;
+#endif
case LDNS_SIGN_HMACMD5:
return len;
break;