Use json_is_true() in place of json_boolean_value() for compatibility
[trust_router.git] / common / tr_dh.c
index 6bda6ee..906d53c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, JANET(UK)
+ * Copyright (c) 2012, 2014, JANET(UK)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #include <openssl/dh.h>
 #include <trust_router/tr_dh.h>
+#include <openssl/bn.h>
+#include <openssl/sha.h>
+#include <talloc.h>
+#include <assert.h>
+#include <tid_internal.h>
+#include <tr_debug.h>
+
 
 unsigned char tr_2048_dhprime[2048/8] = {
   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
@@ -70,7 +77,12 @@ unsigned char tr_2048_dhprime[2048/8] = {
   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 };
 
-DH *tr_create_dh_params(unsigned char *priv_key, 
+DH *tr_dh_new(void)
+{
+  return DH_new();
+}
+
+DH *tr_create_dh_params(unsigned char *priv_key,
                        size_t keylen) {
 
   DH *dh = NULL;
@@ -83,6 +95,7 @@ DH *tr_create_dh_params(unsigned char *priv_key,
       (NULL == (dh->p = BN_new())) ||
       (NULL == (dh->q = BN_new()))) {
     DH_free(dh);
+    return NULL;
   }
 
   BN_set_word(dh->g, 2);
@@ -96,23 +109,23 @@ DH *tr_create_dh_params(unsigned char *priv_key,
 
   DH_check(dh, &dh_err);
   if (0 != dh_err) {
-    fprintf(stderr, "Warning: dh_check failed with %d", dh_err);
+    tr_warning("Warning: dh_check failed with %d", dh_err);
     if (dh_err & DH_CHECK_P_NOT_PRIME)
-      fprintf(stderr, ": p value is not prime\n");
+      tr_warning(": p value is not prime");
     else if (dh_err & DH_CHECK_P_NOT_SAFE_PRIME)
-      fprintf(stderr, ": p value is not a safe prime\n");
+      tr_warning(": p value is not a safe prime");
     else if (dh_err & DH_UNABLE_TO_CHECK_GENERATOR)
-      fprintf(stderr, ": unable to check the generator value\n");
+      tr_warning(": unable to check the generator value");
     else if (dh_err & DH_NOT_SUITABLE_GENERATOR)
-      fprintf (stderr, ": the g value is not a generator\n");
-    else 
-      fprintf(stderr, "\n");
+      tr_warning(": the g value is not a generator");
+    else
+      tr_warning("unhandled error %i", dh_err);
   }
-  
+
   return(dh);
 }
 
-DH *tr_create_matching_dh (unsigned char *priv_key, 
+DH *tr_create_matching_dh (unsigned char *priv_key,
                           size_t keylen,
                           DH *in_dh) {
   DH *dh = NULL;
@@ -122,14 +135,14 @@ DH *tr_create_matching_dh (unsigned char *priv_key,
     return NULL;
 
   if (NULL == (dh = DH_new())) {
-    fprintf(stderr, "Unable to allocate new DH structure.\n");
+    tr_crit("tr_create_matching_dh: unable to allocate new DH structure.");
     return NULL;
   }
 
   if ((NULL == (dh->g = BN_dup(in_dh->g))) ||
       (NULL == (dh->p = BN_dup(in_dh->p)))) {
     DH_free(dh);
-    fprintf(stderr, "Invalid dh parameter values, can't be duped.\n");
+    tr_debug("tr_create_matching_dh: Invalid dh parameter values, can't be duped.");
     return NULL;
   }
 
@@ -140,19 +153,19 @@ DH *tr_create_matching_dh (unsigned char *priv_key,
   DH_generate_key(dh);         /* generates the public key */
   DH_check(dh, &dh_err);
   if (0 != dh_err) {
-    fprintf(stderr, "Warning: dh_check failed with %d", dh_err);
+    tr_warning("Warning: dh_check failed with %d", dh_err);
     if (dh_err & DH_CHECK_P_NOT_PRIME)
-      fprintf(stderr, ": p value is not prime\n");
+      tr_warning(": p value is not prime");
     else if (dh_err & DH_CHECK_P_NOT_SAFE_PRIME)
-      fprintf(stderr, ": p value is not a safe prime\n");
+      tr_warning(": p value is not a safe prime");
     else if (dh_err & DH_UNABLE_TO_CHECK_GENERATOR)
-      fprintf(stderr, ": unable to check the generator value\n");
+      tr_warning(": unable to check the generator value");
     else if (dh_err & DH_NOT_SUITABLE_GENERATOR)
-      fprintf (stderr, ": the g value is not a generator\n");
-    else 
-      fprintf(stderr, "\n");
+      tr_warning(": the g value is not a generator");
+    else
+      tr_warning("unhandled error %i", dh_err);
   }
-  
+
   return(dh);
 }
 
@@ -163,28 +176,88 @@ void tr_destroy_dh_params(DH *dh) {
   }
 }
 
-int tr_compute_dh_key(unsigned char **pbuf, 
-                     BIGNUM *pub_key, 
+DH *tr_dh_dup(DH *in)
+{
+  DH *out=DH_new();
+
+  if (out==NULL)
+    return NULL;
+
+  if (in->g==NULL)
+    out->g=NULL;
+  else {
+    out->g=BN_dup(in->g);
+    if (out->g==NULL) {
+      DH_free(out);
+      return NULL;
+    }
+  }
+
+  if (in->p==NULL)
+    out->p=NULL;
+  else {
+    out->p=BN_dup(in->p);
+    if (out->p==NULL) {
+      DH_free(out);
+      return NULL;
+    }
+  }
+
+  if (in->q==NULL)
+    out->q=NULL;
+  else {
+    out->q=BN_dup(in->q);
+    if (out->q==NULL) {
+      DH_free(out);
+      return NULL;
+    }
+  }
+
+  if (in->priv_key==NULL)
+    out->priv_key=NULL;
+  else {
+    out->priv_key=BN_dup(in->priv_key);
+    if (out->priv_key==NULL) {
+      DH_free(out);
+      return NULL;
+    }
+  }
+
+  if (in->pub_key==NULL)
+    out->pub_key=NULL;
+  else {
+    out->pub_key=BN_dup(in->pub_key);
+    if (out->g==NULL) {
+      DH_free(out);
+      return NULL;
+    }
+  }
+
+  return out;
+}
+
+int tr_compute_dh_key(unsigned char **pbuf,
+                     BIGNUM *pub_key,
                      DH *priv_dh) {
   size_t buflen;
   unsigned char *buf = NULL;;
   int rc = 0;
-  
-  if ((!buf) || 
-      (!pub_key) || 
+
+  if ((!pbuf) ||
+      (!pub_key) ||
       (!priv_dh)) {
-    fprintf(stderr, "tr_compute_dh_key(): Invalid parameters.\n");
+    tr_debug("tr_compute_dh_key: Invalid parameters.");
     return(-1);
   }
   *pbuf = NULL;
   buflen = DH_size(priv_dh);
   buf = malloc(buflen);
   if (buf == NULL) {
-    fprintf(stderr, "out of memory\n");
+    tr_crit("tr_compute_dh_key: out of memory");
     return -1;
   }
 
-  
+
   rc = DH_compute_key(buf, pub_key, priv_dh);
   if (0 <= rc) {
     *pbuf = buf;
@@ -197,3 +270,29 @@ int tr_compute_dh_key(unsigned char **pbuf,
 
 
 
+int tr_dh_pub_hash(TID_REQ *request,
+                  unsigned char **out_digest,
+                  size_t *out_len)
+{
+  const BIGNUM *pub = request->tidc_dh->pub_key;
+  unsigned char *bn_bytes = talloc_zero_size(request, BN_num_bytes(pub));
+  unsigned char *digest = talloc_zero_size(request, SHA_DIGEST_LENGTH+1);
+  assert(bn_bytes && digest);
+  BN_bn2bin(pub, bn_bytes);
+  SHA1(bn_bytes, BN_num_bytes(pub), digest);
+  *out_digest = digest;
+  *out_len = SHA_DIGEST_LENGTH;
+
+  talloc_free(bn_bytes);
+  return 0;
+}
+
+void tr_dh_free(unsigned char *dh_buf)
+{
+  free(dh_buf);
+}
+
+void tr_dh_destroy(DH *dh)
+{
+  DH_free(dh);
+}