aboutsummaryrefslogtreecommitdiff
path: root/src/or/torcert.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2015-05-28 10:47:42 -0400
committerNick Mathewson <nickm@torproject.org>2015-05-28 10:47:47 -0400
commit3bee74c6d115131f4850a07a5c12db21ae6f3193 (patch)
treedd261f2ef2007364c54043af54bd6aea9c300adb /src/or/torcert.c
parent32f59d73372f5843ceb305a9d58387573d90f4f6 (diff)
downloadtor-3bee74c6d115131f4850a07a5c12db21ae6f3193.tar.gz
tor-3bee74c6d115131f4850a07a5c12db21ae6f3193.zip
Generate weird certificates correctly
(Our link protocol assumes that the link cert certifies the TLS key, and there is an RSA->Ed25519 crosscert)
Diffstat (limited to 'src/or/torcert.c')
-rw-r--r--src/or/torcert.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/src/or/torcert.c b/src/or/torcert.c
index 15347307e1..e2ddffd7a9 100644
--- a/src/or/torcert.c
+++ b/src/or/torcert.c
@@ -1,12 +1,13 @@
/* Copyright (c) 2014, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "torcert.h"
#include "crypto.h"
+#include "torcert.h"
#include "ed25519_cert.h"
#include "torlog.h"
#include "util.h"
#include "compat.h"
+#include "link_handshake.h"
/** Helper for tor_cert_create(): signs any 32 bytes, not just an ed25519
* key.
@@ -237,3 +238,43 @@ tor_cert_opt_eq(const tor_cert_t *cert1, const tor_cert_t *cert2)
return 0;
return tor_cert_eq(cert1, cert2);
}
+
+/** Create new cross-certification object to certify <b>ed_key</b> as the
+ * master ed25519 identity key for the RSA identity key <b>rsa_key</b>.
+ * Allocates and stores the encoded certificate in *<b>cert</b>, and returns
+ * the number of bytes stored. Returns negative on error.*/
+ssize_t
+tor_make_rsa_ed25519_crosscert(const ed25519_public_key_t *ed_key,
+ const crypto_pk_t *rsa_key,
+ time_t expires,
+ uint8_t **cert)
+{
+ uint8_t *res;
+
+ rsa_ed_crosscert_t *cc = rsa_ed_crosscert_new();
+ memcpy(cc->ed_key, ed_key->pubkey, ED25519_PUBKEY_LEN);
+ cc->expiration = (uint32_t) CEIL_DIV(expires, 3600);
+ cc->sig_len = crypto_pk_keysize(rsa_key);
+ rsa_ed_crosscert_setlen_sig(cc, crypto_pk_keysize(rsa_key));
+
+ ssize_t alloc_sz = rsa_ed_crosscert_encoded_len(cc);
+ tor_assert(alloc_sz > 0);
+ res = tor_malloc_zero(alloc_sz);
+ ssize_t sz = rsa_ed_crosscert_encode(res, alloc_sz, cc);
+ tor_assert(sz > 0 && sz <= alloc_sz);
+
+ const int signed_part_len = 32 + 4;
+ int siglen = crypto_pk_private_sign(rsa_key,
+ (char*)rsa_ed_crosscert_getarray_sig(cc),
+ rsa_ed_crosscert_getlen_sig(cc),
+ (char*)res, signed_part_len);
+ tor_assert(siglen > 0 && siglen <= (int)crypto_pk_keysize(rsa_key));
+ tor_assert(siglen <= UINT8_MAX);
+ cc->sig_len = siglen;
+ rsa_ed_crosscert_setlen_sig(cc, siglen);
+
+ sz = rsa_ed_crosscert_encode(res, alloc_sz, cc);
+ rsa_ed_crosscert_free(cc);
+ *cert = res;
+ return sz;
+}