aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/crypto.c39
-rw-r--r--src/common/crypto.h4
-rw-r--r--src/common/tortls.c49
-rw-r--r--src/common/tortls.h4
4 files changed, 71 insertions, 25 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 538f946ae..b2ddbb173 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -349,7 +349,7 @@ int crypto_pk_read_private_key_from_file(crypto_pk_env_t *env, FILE *src)
return 0;
}
-int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, unsigned char *keyfile)
+int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const char *keyfile)
{
FILE *f_pr;
int retval = 0;
@@ -618,6 +618,43 @@ int crypto_pk_private_sign(crypto_pk_env_t *env, unsigned char *from, int fromle
}
}
+int
+crypto_pk_get_fingerprint(crypto_pk_env_t *pk, char *fp_out)
+{
+ unsigned char *buf, *bufp;
+ unsigned char digest[20];
+ int len;
+ int i;
+ assert(pk->type == CRYPTO_PK_RSA);
+ len = i2d_RSAPublicKey((RSA*)pk->key, NULL);
+ if (len < 0)
+ return -1;
+ if (len<FINGERPRINT_LEN+1) len = FINGERPRINT_LEN+1;
+ buf = bufp = tor_malloc(len+1);
+ len = i2d_RSAPublicKey((RSA*)pk->key, &bufp);
+ if (len < 0) {
+ free(buf);
+ return -1;
+ }
+ if (crypto_SHA_digest(buf, len, digest) < 0) {
+ free(buf);
+ return -1;
+ }
+ bufp = buf;
+ for (i = 0; i < 20; ++i) {
+ sprintf(bufp,"%02X",digest[i]);
+ bufp += 2;
+ if (i%2 && i != 19) {
+ *bufp++ = ' ';
+ }
+ }
+ *bufp = '\0';
+ assert(strlen(buf) == FINGERPRINT_LEN);
+ strcpy(fp_out, buf);
+ free(buf);
+ return 0;
+}
+
/* symmetric crypto */
int crypto_cipher_generate_key(crypto_cipher_env_t *env)
{
diff --git a/src/common/crypto.h b/src/common/crypto.h
index f723e7195..ccd48fa56 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -42,7 +42,7 @@ int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, char *src, int l
int crypto_pk_write_private_key_to_file(crypto_pk_env_t *env, FILE *dest);
int crypto_pk_write_public_key_to_file(crypto_pk_env_t *env, FILE *dest);
int crypto_pk_check_key(crypto_pk_env_t *env);
-int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, unsigned char *keyfile);
+int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const char *keyfile);
int crypto_pk_set_key(crypto_pk_env_t *env, unsigned char *key);
int crypto_pk_cmp_keys(crypto_pk_env_t *a, crypto_pk_env_t *b);
@@ -53,6 +53,8 @@ int crypto_pk_public_encrypt(crypto_pk_env_t *env, unsigned char *from, int from
int crypto_pk_private_decrypt(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to, int padding);
int crypto_pk_private_sign(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to);
int crypto_pk_public_checksig(crypto_pk_env_t *env, unsigned char *from, int fromlen, unsigned char *to);
+#define FINGERPRINT_LEN 49
+int crypto_pk_get_fingerprint(crypto_pk_env_t *pk, char *fp_out);
int base64_encode(char *dest, int destlen, char *src, int srclen);
int base64_decode(char *dest, int destlen, char *src, int srclen);
diff --git a/src/common/tortls.c b/src/common/tortls.c
index f7d961ab8..a1d5b2c5e 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -33,6 +33,9 @@ struct tor_tls_st {
int isServer;
};
+static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
+ const char *nickname);
+
/* global tls context, keep it here because nobody else needs to touch it */
static tor_tls_context *global_tls_context=NULL;
static int tls_library_is_initialized = 0;
@@ -111,8 +114,9 @@ static int always_accept_verify_cb(int preverify_ok,
* commonName 'nickname', and write it, PEM-encoded, to the file named
* by 'certfile'. Return 0 on success, -1 for failure.
*/
-int
-tor_tls_write_certificate(char *certfile, crypto_pk_env_t *rsa, char *nickname)
+X509 *
+tor_tls_create_certificate(crypto_pk_env_t *rsa,
+ const char *nickname)
{
time_t start_time, end_time;
EVP_PKEY *pkey = NULL;
@@ -120,15 +124,15 @@ tor_tls_write_certificate(char *certfile, crypto_pk_env_t *rsa, char *nickname)
X509_NAME *name = NULL;
BIO *out = NULL;
int nid;
- int r;
+ int err;
tor_tls_init();
start_time = time(NULL);
- assert(rsa);
+ assert(rsa && nickname);
if (!(pkey = _crypto_pk_env_get_evp_pkey(rsa)))
- return -1;
+ return NULL;
if (!(x509 = X509_new()))
goto error;
if (!(X509_set_version(x509, 2)))
@@ -143,7 +147,7 @@ tor_tls_write_certificate(char *certfile, crypto_pk_env_t *rsa, char *nickname)
"TOR", -1, -1, 0))) goto error;
if ((nid = OBJ_txt2nid("commonName")) == NID_undef) goto error;
if (!(X509_NAME_add_entry_by_NID(name, nid, MBSTRING_ASC,
- nickname, -1, -1, 0))) goto error;
+ (char*)nickname, -1, -1, 0))) goto error;
if (!(X509_set_issuer_name(x509, name)))
goto error;
@@ -158,25 +162,21 @@ tor_tls_write_certificate(char *certfile, crypto_pk_env_t *rsa, char *nickname)
goto error;
if (!X509_sign(x509, pkey, EVP_sha1()))
goto error;
- if (!(out = BIO_new_file(certfile, "w")))
- goto error;
- if (!(PEM_write_bio_X509(out, x509)))
- goto error;
- r = 0;
+ err = 0;
goto done;
error:
- r = -1;
+ err = 1;
done:
if (out)
BIO_free(out);
- if (x509)
+ if (x509 && err)
X509_free(x509);
if (pkey)
EVP_PKEY_free(pkey);
if (name)
X509_NAME_free(name);
- return r;
+ return x509;
}
@@ -201,16 +201,24 @@ tor_tls_write_certificate(char *certfile, crypto_pk_env_t *rsa, char *nickname)
* used for that certificate. Return -1 if failure, else 0.
*/
int
-tor_tls_context_new(char *certfile, crypto_pk_env_t *rsa, int isServer)
+tor_tls_context_new(crypto_pk_env_t *rsa,
+ int isServer, const char *nickname)
{
crypto_dh_env_t *dh = NULL;
EVP_PKEY *pkey = NULL;
tor_tls_context *result;
-
- assert((certfile && rsa) || (!certfile && !rsa));
-
+ X509 *cert = NULL;
+
tor_tls_init();
+ if (rsa) {
+ cert = tor_tls_create_certificate(rsa, nickname);
+ if (!cert) {
+ log(LOG_ERR, "Error creating certificate");
+ return NULL;
+ }
+ }
+
result = tor_malloc(sizeof(tor_tls_context));
result->ctx = NULL;
#ifdef EVERYONE_HAS_AES
@@ -225,8 +233,7 @@ tor_tls_context_new(char *certfile, crypto_pk_env_t *rsa, int isServer)
#endif
if (!SSL_CTX_set_cipher_list(result->ctx, CIPHER_LIST))
goto error;
- if (certfile && !SSL_CTX_use_certificate_file(result->ctx,certfile,
- SSL_FILETYPE_PEM))
+ if (cert && !SSL_CTX_use_certificate(result->ctx,cert))
goto error;
SSL_CTX_set_session_cache_mode(result->ctx, SSL_SESS_CACHE_OFF);
if (rsa) {
@@ -236,7 +243,7 @@ tor_tls_context_new(char *certfile, crypto_pk_env_t *rsa, int isServer)
goto error;
EVP_PKEY_free(pkey);
pkey = NULL;
- if (certfile) {
+ if (cert) {
if (!SSL_CTX_check_private_key(result->ctx))
goto error;
}
diff --git a/src/common/tortls.h b/src/common/tortls.h
index 2f45c4da3..2c8749cea 100644
--- a/src/common/tortls.h
+++ b/src/common/tortls.h
@@ -16,8 +16,8 @@ typedef struct tor_tls_st tor_tls;
#define TOR_TLS_WANTWRITE -1
#define TOR_TLS_DONE 0
-int tor_tls_write_certificate(char *certfile, crypto_pk_env_t *rsa, char *nickname);
-int tor_tls_context_new(char *certfile, crypto_pk_env_t *rsa, int isServer);
+/* X509* tor_tls_write_certificate(char *certfile, crypto_pk_env_t *rsa, char *nickname); */
+int tor_tls_context_new(crypto_pk_env_t *rsa, int isServer, const char *nickname);
tor_tls *tor_tls_new(int sock, int isServer);
void tor_tls_free(tor_tls *tls);
int tor_tls_peer_has_cert(tor_tls *tls);