]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
Fixed out of buffer reference, in case . is read, then rd_strlen==size==1 and data...
authorWouter Wijngaards <wouter@NLnetLabs.nl>
Wed, 5 Aug 2009 14:47:20 +0000 (14:47 +0000)
committerWouter Wijngaards <wouter@NLnetLabs.nl>
Wed, 5 Aug 2009 14:47:20 +0000 (14:47 +0000)
configure.ac
dnssec_sign.c
dnssec_verify.c
examples/configure.ac
host2str.c
keys.c
ldns/keys.h
rr.c
rr_functions.c

index af4dcb980726c0f1db5ace13e5a52d9c86fed604..18b07e0df39b795ac84e9a32b849cf3cb214b0a7 100644 (file)
@@ -75,6 +75,16 @@ AC_CHECK_TYPE(uint64_t, unsigned long long)
 # 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)
@@ -88,6 +98,19 @@ case "$enable_sha2" in
         ;;
 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)
@@ -108,16 +131,6 @@ if test "x$enable_rpath" = xyes; then
     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()
index d75db20152c5f9b3c80f01385265e6a49d31989e..fa905e6ae151e8de47efee606657b6bb8738816b 100644 (file)
@@ -141,6 +141,14 @@ ldns_sign_public_buffer(ldns_buffer *sign_buf, ldns_key *current_key)
                                   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,
index 18b18c8e69e493d238806156000e697f74ee3e80..640899f47e5f632a36fbf3695043a0ca78c0b9ff 100644 (file)
@@ -1510,6 +1510,42 @@ ldns_dnssec_verify_denial_nsec3(ldns_rr *rr,
 }
 #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)
@@ -1560,6 +1596,12 @@ ldns_verify_rrsig_buffers_raw(unsigned char* sig, size_t siglen,
                                                                            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,
@@ -1645,6 +1687,9 @@ ldns_rrsig2rawsig_buffer(ldns_buffer* rawsig_buf, ldns_rr* rrsig)
 #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) {
@@ -2109,12 +2154,12 @@ ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
                                                  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,
@@ -2135,7 +2180,6 @@ ldns_verify_rrsig_rsasha512_raw(unsigned char* sig,
 }
 
 
-
 ldns_status
 ldns_verify_rrsig_rsamd5_raw(unsigned char* sig,
                                            size_t siglen,
index cea17600729c3d603f5c68d691c7ccc09d649342..4d8fce407afa6443d207055251b21f352e00f64f 100644 (file)
@@ -210,7 +210,18 @@ case "$enable_sha2" in
         ;;
 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.)])
index 2ac237d1743fc63e27f44ac42d74fe157eeaba19..cecb4129f46ec8406bf654ce84b1b3c69409baab 100644 (file)
@@ -1350,6 +1350,26 @@ ldns_hmac_key2buffer_str(ldns_buffer *output, const ldns_key *k)
 }
 #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)
 {
@@ -1644,6 +1664,14 @@ 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 */
diff --git a/keys.c b/keys.c
index 1b200a911a91dbf1311994dd4647d68e54d573bc..19c8e62f2493865b257c55550b3298ee06a31034 100644 (file)
--- a/keys.c
+++ b/keys.c
@@ -27,6 +27,9 @@ ldns_lookup_table ldns_signing_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" },
@@ -100,6 +103,64 @@ ldns_key_new_frm_engine(ldns_key **key, ENGINE *e, char *key_id, ldns_algorithm
 }
 #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)
 {
@@ -183,6 +244,14 @@ 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) {
@@ -231,6 +300,15 @@ ldns_key_new_frm_fp_l(ldns_key **key, FILE *fp, int *line_nr)
                        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;
@@ -589,6 +667,39 @@ ldns_key_new_frm_algorithm(ldns_signing_algorithm alg, uint16_t size)
 
                        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;
@@ -949,6 +1060,24 @@ ldns_key_dsa2bin(unsigned char *data, DSA *k, uint16_t *size)
        *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 *
@@ -1057,6 +1186,19 @@ ldns_key2rr(const ldns_key *k)
                        }
 #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:
index 8c75b243c795955ba96527d065442cdedb1aa6f6..977dcaae1f8e590eaa56faedd92afedd01e44616 100644 (file)
@@ -48,6 +48,7 @@ enum ldns_enum_algorithm
         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
@@ -60,7 +61,8 @@ typedef enum ldns_enum_algorithm ldns_algorithm;
 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;
 
@@ -76,6 +78,7 @@ enum ldns_enum_signing_algorithm
        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 */
diff --git a/rr.c b/rr.c
index 5a9dfbde91b172432c082c393f24f666cedbf0c4..a900bf3f01ee80302bacfec9c6b34e781bf2ec04 100644 (file)
--- a/rr.c
+++ b/rr.c
@@ -468,7 +468,8 @@ ldns_rr_new_frm_str_internal(ldns_rr **newrr, const char *str,
                                                                        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);
index 7afd8675d4eff68236db6c3df2f83a490ee0b470..3297f7a916ebbe89784ecd44df348e733bb387f8 100644 (file)
@@ -311,6 +311,11 @@ ldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
                        return 0;
                }
                break;
+#ifdef USE_GOST
+       case LDNS_SIGN_GOST:
+               return 512;
+               break;
+#endif
        case LDNS_SIGN_HMACMD5:
                return len;
                break;