Loading src/common/tortls.c +65 −4 Original line number Diff line number Diff line Loading @@ -38,6 +38,11 @@ static tor_tls_context *global_tls_context=NULL; #define _TOR_TLS_SYSCALL -6 #define _TOR_TLS_ZERORETURN -5 /* These functions are declared in crypto.c but not exported. */ RSA *_crypto_pk_env_get_rsa(crypto_pk_env_t *env); crypto_pk_env_t *_crypto_new_pk_env_rsa(RSA *rsa); static int tor_tls_get_error(tor_tls *tls, int r, int extra) { Loading Loading @@ -83,8 +88,8 @@ tor_tls_write_certificate(char *certfile, crypto_pk_env_t *rsa, char *nickname) start_time = time(NULL); assert(rsa && rsa->type == CRYPTO_PK_RSA); if (!(_rsa = RSAPrivateKey_dup((RSA*)rsa->key))) assert(rsa); if (!(_rsa = RSAPrivateKey_dup(_crypto_pk_env_get_rsa(rsa)))) /* XXX we have a crypto_pk_dup_key(), it's a shame we can't use it here */ return -1; if (!(pkey = EVP_PKEY_new())) Loading Loading @@ -144,7 +149,6 @@ tor_tls_context_new(char *certfile, crypto_pk_env_t *rsa, int isServer) EVP_PKEY *pkey = NULL; tor_tls_context *result; assert(!rsa || rsa->type == CRYPTO_PK_RSA); assert((certfile && rsa) || (!certfile && !rsa)); result = tor_malloc(sizeof(tor_tls_context)); Loading @@ -159,7 +163,7 @@ tor_tls_context_new(char *certfile, crypto_pk_env_t *rsa, int isServer) return -1; SSL_CTX_set_session_cache_mode(result->ctx, SSL_SESS_CACHE_OFF); if (rsa) { if (!(_rsa = RSAPrivateKey_dup((RSA*)rsa->key))) if (!(_rsa = RSAPrivateKey_dup(_crypto_pk_env_get_rsa(rsa)))) return -1; if (!(pkey = EVP_PKEY_new())) return -1; Loading Loading @@ -329,3 +333,60 @@ tor_tls_shutdown(tor_tls *tls) } } /* Return true iff this TLS connection is authenticated. */ int tor_tls_peer_has_cert(tor_tls *tls) { X509 *cert; if (!(cert = SSL_get_peer_certificate(tls->ssl))) return 0; X509_free(cert); return 1; } /* If the provided tls connection is authenticated and has a * certificate that is currently valid and is correctly self-signed, * return its public key. Otherwise return NULL. */ crypto_pk_env_t * tor_tls_verify(tor_tls *tls) { X509 *cert = NULL; EVP_PKEY *pkey = NULL; RSA *rsa = NULL; time_t now; crypto_pk_env_t *r = NULL; if (!(cert = SSL_get_peer_certificate(tls->ssl))) return 0; now = time(NULL); if (X509_cmp_time(X509_get_notBefore(cert), &now) > 0) goto done; if (X509_cmp_time(X509_get_notAfter(cert), &now) < 0) goto done; /* Get the public key. */ if (!(pkey = X509_get_pubkey(cert))) goto done; if (X509_verify(cert, pkey) <= 0) goto done; rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); pkey = NULL; if (!rsa) goto done; r = _crypto_new_pk_env_rsa(rsa); rsa = NULL; done: if (cert) X509_free(cert); if (pkey) EVP_PKEY_free(pkey); if (rsa) RSA_free(rsa); return r; } src/common/tortls.h +2 −2 Original line number Diff line number Diff line Loading @@ -20,8 +20,8 @@ int tor_tls_write_certificate(char *certfile, crypto_pk_env_t *rsa, char *nickna int tor_tls_context_new(char *certfile, crypto_pk_env_t *rsa, int isServer); tor_tls *tor_tls_new(int sock, int isServer); void tor_tls_free(tor_tls *tls); int tor_tls_peer_is_valid(tor_tls *tls); crypto_pk_env_t *tor_tls_get_peer_pk(tor_tls *tls); int tor_tls_peer_has_cert(tor_tls *tls); crypto_pk_env_t *tor_tls_verify(tor_tls *tls); int tor_tls_read(tor_tls *tls, char *cp, int len); int tor_tls_write(tor_tls *tls, char *cp, int n); int tor_tls_handshake(tor_tls *tls); Loading Loading
src/common/tortls.c +65 −4 Original line number Diff line number Diff line Loading @@ -38,6 +38,11 @@ static tor_tls_context *global_tls_context=NULL; #define _TOR_TLS_SYSCALL -6 #define _TOR_TLS_ZERORETURN -5 /* These functions are declared in crypto.c but not exported. */ RSA *_crypto_pk_env_get_rsa(crypto_pk_env_t *env); crypto_pk_env_t *_crypto_new_pk_env_rsa(RSA *rsa); static int tor_tls_get_error(tor_tls *tls, int r, int extra) { Loading Loading @@ -83,8 +88,8 @@ tor_tls_write_certificate(char *certfile, crypto_pk_env_t *rsa, char *nickname) start_time = time(NULL); assert(rsa && rsa->type == CRYPTO_PK_RSA); if (!(_rsa = RSAPrivateKey_dup((RSA*)rsa->key))) assert(rsa); if (!(_rsa = RSAPrivateKey_dup(_crypto_pk_env_get_rsa(rsa)))) /* XXX we have a crypto_pk_dup_key(), it's a shame we can't use it here */ return -1; if (!(pkey = EVP_PKEY_new())) Loading Loading @@ -144,7 +149,6 @@ tor_tls_context_new(char *certfile, crypto_pk_env_t *rsa, int isServer) EVP_PKEY *pkey = NULL; tor_tls_context *result; assert(!rsa || rsa->type == CRYPTO_PK_RSA); assert((certfile && rsa) || (!certfile && !rsa)); result = tor_malloc(sizeof(tor_tls_context)); Loading @@ -159,7 +163,7 @@ tor_tls_context_new(char *certfile, crypto_pk_env_t *rsa, int isServer) return -1; SSL_CTX_set_session_cache_mode(result->ctx, SSL_SESS_CACHE_OFF); if (rsa) { if (!(_rsa = RSAPrivateKey_dup((RSA*)rsa->key))) if (!(_rsa = RSAPrivateKey_dup(_crypto_pk_env_get_rsa(rsa)))) return -1; if (!(pkey = EVP_PKEY_new())) return -1; Loading Loading @@ -329,3 +333,60 @@ tor_tls_shutdown(tor_tls *tls) } } /* Return true iff this TLS connection is authenticated. */ int tor_tls_peer_has_cert(tor_tls *tls) { X509 *cert; if (!(cert = SSL_get_peer_certificate(tls->ssl))) return 0; X509_free(cert); return 1; } /* If the provided tls connection is authenticated and has a * certificate that is currently valid and is correctly self-signed, * return its public key. Otherwise return NULL. */ crypto_pk_env_t * tor_tls_verify(tor_tls *tls) { X509 *cert = NULL; EVP_PKEY *pkey = NULL; RSA *rsa = NULL; time_t now; crypto_pk_env_t *r = NULL; if (!(cert = SSL_get_peer_certificate(tls->ssl))) return 0; now = time(NULL); if (X509_cmp_time(X509_get_notBefore(cert), &now) > 0) goto done; if (X509_cmp_time(X509_get_notAfter(cert), &now) < 0) goto done; /* Get the public key. */ if (!(pkey = X509_get_pubkey(cert))) goto done; if (X509_verify(cert, pkey) <= 0) goto done; rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); pkey = NULL; if (!rsa) goto done; r = _crypto_new_pk_env_rsa(rsa); rsa = NULL; done: if (cert) X509_free(cert); if (pkey) EVP_PKEY_free(pkey); if (rsa) RSA_free(rsa); return r; }
src/common/tortls.h +2 −2 Original line number Diff line number Diff line Loading @@ -20,8 +20,8 @@ int tor_tls_write_certificate(char *certfile, crypto_pk_env_t *rsa, char *nickna int tor_tls_context_new(char *certfile, crypto_pk_env_t *rsa, int isServer); tor_tls *tor_tls_new(int sock, int isServer); void tor_tls_free(tor_tls *tls); int tor_tls_peer_is_valid(tor_tls *tls); crypto_pk_env_t *tor_tls_get_peer_pk(tor_tls *tls); int tor_tls_peer_has_cert(tor_tls *tls); crypto_pk_env_t *tor_tls_verify(tor_tls *tls); int tor_tls_read(tor_tls *tls, char *cp, int len); int tor_tls_write(tor_tls *tls, char *cp, int n); int tor_tls_handshake(tor_tls *tls); Loading