aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorYawning Angel <yawning@schwanenlied.me>2015-04-25 08:23:15 +0000
committerNick Mathewson <nickm@torproject.org>2015-04-28 10:19:08 -0400
commit915c7438a77edfaf3103b69cb494a4f069a79a0c (patch)
tree1aec80453d2aa691de928349d233a85374b4305c /src/common
parent63a90f2df4dcd7fff862ca3849f3aa3b1dec7e84 (diff)
downloadtor-915c7438a77edfaf3103b69cb494a4f069a79a0c.tar.gz
tor-915c7438a77edfaf3103b69cb494a4f069a79a0c.zip
Add "ADD_ONION"/"DEL_ONION" and "GETINFO onions/*" to the controller.
These commands allow for the creation and management of ephemeral Onion ("Hidden") services that are either bound to the lifetime of the originating control connection, or optionally the lifetime of the tor instance. Implements #6411.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/crypto.c72
-rw-r--r--src/common/crypto.h3
2 files changed, 75 insertions, 0 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 7857a54951..8038631f18 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -1397,6 +1397,78 @@ crypto_pk_get_hashed_fingerprint(crypto_pk_t *pk, char *fp_out)
return 0;
}
+/** Given a crypto_pk_t <b>pk</b>, allocate a new buffer containing the
+ * Base64 encoding of the DER representation of the private key as a NUL
+ * terminated string, and return it via <b>priv_out</b>. Return 0 on
+ * sucess, -1 on failure.
+ *
+ * It is the caller's responsibility to sanitize and free the resulting buffer.
+ */
+int
+crypto_pk_base64_encode(const crypto_pk_t *pk, char **priv_out)
+{
+ unsigned char *der = NULL;
+ int der_len;
+ int ret = -1;
+
+ *priv_out = NULL;
+
+ der_len = i2d_RSAPrivateKey(pk->key, &der);
+ if (der_len < 0 || der == NULL)
+ return ret;
+
+ size_t priv_len = base64_encode_size(der_len, 0) + 1;
+ char *priv = tor_malloc_zero(priv_len);
+ if (base64_encode(priv, priv_len, (char *)der, der_len, 0) >= 0) {
+ *priv_out = priv;
+ ret = 0;
+ } else {
+ tor_free(priv);
+ }
+
+ memwipe(der, 0, der_len);
+ OPENSSL_free(der);
+ return ret;
+}
+
+/** Given a string containing the Base64 encoded DER representation of the
+ * private key <b>str</b>, decode and return the result on success, or NULL
+ * on failure.
+ */
+crypto_pk_t *
+crypto_pk_base64_decode(const char *str, size_t len)
+{
+ crypto_pk_t *pk = NULL;
+
+ char *der = tor_malloc_zero(len + 1);
+ int der_len = base64_decode(der, len, str, len);
+ if (der_len <= 0) {
+ log_warn(LD_CRYPTO, "Stored RSA private key seems corrupted (base64).");
+ goto out;
+ }
+
+ const unsigned char *dp = (unsigned char*)der; /* Shut the compiler up. */
+ RSA *rsa = d2i_RSAPrivateKey(NULL, &dp, der_len);
+ if (!rsa) {
+ crypto_log_errors(LOG_WARN, "decoding private key");
+ goto out;
+ }
+
+ pk = crypto_new_pk_from_rsa_(rsa);
+
+ /* Make sure it's valid. */
+ if (crypto_pk_check_key(pk) <= 0) {
+ crypto_pk_free(pk);
+ pk = NULL;
+ goto out;
+ }
+
+ out:
+ memwipe(der, 0, len + 1);
+ tor_free(der);
+ return pk;
+}
+
/* symmetric crypto */
/** Return a pointer to the key set for the cipher in <b>env</b>.
diff --git a/src/common/crypto.h b/src/common/crypto.h
index 1ac02ea7a5..8b620d910c 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -184,6 +184,9 @@ int crypto_pk_get_all_digests(crypto_pk_t *pk, digests_t *digests_out);
int crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out,int add_space);
int crypto_pk_get_hashed_fingerprint(crypto_pk_t *pk, char *fp_out);
+int crypto_pk_base64_encode(const crypto_pk_t *pk, char **priv_out);
+crypto_pk_t *crypto_pk_base64_decode(const char *str, size_t len);
+
/* symmetric crypto */
const char *crypto_cipher_get_key(crypto_cipher_t *env);