diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/crypto.c | 39 | ||||
-rw-r--r-- | src/common/crypto.h | 4 | ||||
-rw-r--r-- | src/common/tortls.c | 49 | ||||
-rw-r--r-- | src/common/tortls.h | 4 |
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); |