diff options
| author | Dirk Engling <erdgeist@erdgeist.org> | 2022-05-20 01:55:16 +0200 |
|---|---|---|
| committer | Dirk Engling <erdgeist@erdgeist.org> | 2022-05-20 01:55:16 +0200 |
| commit | 5ded7d393d450303b74aba21df0a6755bbc4360d (patch) | |
| tree | 8683be1a07f19ce9d49d9d601a1b5aef06d5af87 | |
| parent | b8c73169ab48dea503091f2d16d90c872d4ac99f (diff) | |
Move pinned fingerprint handler out of openssls scope
| -rwxr-xr-x | vchat-tls.c | 90 |
1 files changed, 50 insertions, 40 deletions
diff --git a/vchat-tls.c b/vchat-tls.c index e6e4cc1..c4b014a 100755 --- a/vchat-tls.c +++ b/vchat-tls.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <stdlib.h> | 19 | #include <stdlib.h> |
| 20 | #include <string.h> | 20 | #include <string.h> |
| 21 | #include <assert.h> | 21 | #include <assert.h> |
| 22 | #include <errno.h> | ||
| 22 | 23 | ||
| 23 | #include <readline/readline.h> | 24 | #include <readline/readline.h> |
| 24 | 25 | ||
| @@ -69,6 +70,52 @@ void vc_x509store_setcertfile(vc_x509store_t *store, char *file) { | |||
| 69 | store->flags |= VC_X509S_USE_CERTIFICATE; | 70 | store->flags |= VC_X509S_USE_CERTIFICATE; |
| 70 | } | 71 | } |
| 71 | 72 | ||
| 73 | static int verify_or_store_fingerprint(const char *fingerprint) { | ||
| 74 | char *fingerprint_file_path = tilde_expand(getstroption(CF_FINGERPRINT)); | ||
| 75 | if (!fingerprint_file_path) { | ||
| 76 | writecf(FS_ERR, "[SSL FINGERPRINT ] The CF_FINGERPRINT path is not set."); | ||
| 77 | return -1; | ||
| 78 | } | ||
| 79 | |||
| 80 | FILE *fingerprint_file = fopen(fingerprint_file_path, "r"); | ||
| 81 | if (fingerprint_file) { | ||
| 82 | /* Read fingerprint from file */ | ||
| 83 | char old_fingerprint[128]; | ||
| 84 | char * r = fgets(old_fingerprint, sizeof(old_fingerprint), fingerprint_file); | ||
| 85 | fclose(fingerprint_file); | ||
| 86 | |||
| 87 | if (r) { | ||
| 88 | /* chomp */ | ||
| 89 | char *nl = strchr(r, '\n'); | ||
| 90 | if (nl) *nl = 0; | ||
| 91 | |||
| 92 | /* verify fingerprint matches stored version */ | ||
| 93 | if (!strcmp(fingerprint, old_fingerprint)) | ||
| 94 | goto cleanup_happy; | ||
| 95 | } | ||
| 96 | |||
| 97 | snprintf(tmpstr, TMPSTRSIZE, "[SSL FINGERPRINT ] Found pinned fingerprint (in %s) %s but expected %s", r ? old_fingerprint : "<FILE READ ERROR>", getstroption(CF_FINGERPRINT), fingerprint); | ||
| 98 | writecf(FS_ERR, tmpstr); | ||
| 99 | writecf(FS_ERR, "[SSL CONNECT ERROR] Fingerprint mismatch! Server cert updated?"); | ||
| 100 | free(fingerprint_file_path); | ||
| 101 | return 1; | ||
| 102 | } else | ||
| 103 | writecf(FS_ERR, "[WARNING] No pinned Fingerprint found!"); | ||
| 104 | |||
| 105 | fingerprint_file = fopen(fingerprint_file_path, "w"); | ||
| 106 | if (!fingerprint_file) { | ||
| 107 | snprintf (tmpstr, TMPSTRSIZE, "[WARNING] Can't write fingerprint file, %s.", strerror(errno)); | ||
| 108 | writecf(FS_ERR, tmpstr); | ||
| 109 | } else { | ||
| 110 | fputs(fingerprint, fingerprint_file); | ||
| 111 | fclose(fingerprint_file); | ||
| 112 | writecf(FS_SERV, "Stored pinned fingerprint."); | ||
| 113 | } | ||
| 114 | cleanup_happy: | ||
| 115 | free(fingerprint_file_path); | ||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | |||
| 72 | #ifdef TLS_LIB_OPENSSL | 119 | #ifdef TLS_LIB_OPENSSL |
| 73 | 120 | ||
| 74 | #include <openssl/err.h> | 121 | #include <openssl/err.h> |
| @@ -186,10 +233,9 @@ int vc_tls_connect( int serverfd, vc_x509store_t *vc_store ) | |||
| 186 | unsigned char fingerprint_bin[EVP_MAX_MD_SIZE]; | 233 | unsigned char fingerprint_bin[EVP_MAX_MD_SIZE]; |
| 187 | unsigned int fingerprint_len; | 234 | unsigned int fingerprint_len; |
| 188 | 235 | ||
| 189 | FILE *fingerprint_file = NULL; | ||
| 190 | char * fp = fingerprint; | 236 | char * fp = fingerprint; |
| 191 | 237 | ||
| 192 | long result, j; | 238 | long j; |
| 193 | 239 | ||
| 194 | if( !ctx ) | 240 | if( !ctx ) |
| 195 | goto all_errors; | 241 | goto all_errors; |
| @@ -249,44 +295,8 @@ int vc_tls_connect( int serverfd, vc_x509store_t *vc_store ) | |||
| 249 | /* we don't need the peercert anymore */ | 295 | /* we don't need the peercert anymore */ |
| 250 | X509_free(peercert); | 296 | X509_free(peercert); |
| 251 | 297 | ||
| 252 | /* verify fingerprint */ | 298 | if (getintoption(CF_PINFINGER) && verify_or_store_fingerprint(fingerprint)) |
| 253 | if (getintoption(CF_PINFINGER)) { | 299 | return 1; |
| 254 | |||
| 255 | fingerprint_file = fopen(tilde_expand(getstroption(CF_FINGERPRINT)), "r"); | ||
| 256 | if (fingerprint_file) { | ||
| 257 | |||
| 258 | /* Read fingerprint from file */ | ||
| 259 | char old_fingerprint[EVP_MAX_MD_SIZE*4]; | ||
| 260 | char * r = fgets(old_fingerprint, sizeof(old_fingerprint), fingerprint_file); | ||
| 261 | fclose(fingerprint_file); | ||
| 262 | |||
| 263 | if (r) { | ||
| 264 | /* chomp */ | ||
| 265 | char *nl = strchr(r, '\n'); | ||
| 266 | if (nl) *nl = 0; | ||
| 267 | |||
| 268 | /* verify fingerprint matches stored version */ | ||
| 269 | if (!strcmp(fingerprint, old_fingerprint)) | ||
| 270 | return 0; | ||
| 271 | } | ||
| 272 | |||
| 273 | snprintf(tmpstr, TMPSTRSIZE, "[SSL FINGERPRINT ] %s (from %s)", r ? old_fingerprint : "<FILE READ ERROR>", getstroption(CF_FINGERPRINT)); | ||
| 274 | writecf(FS_ERR, tmpstr); | ||
| 275 | writecf(FS_ERR, "[SSL CONNECT ERROR] Fingerprint mismatch! Server cert updated?"); | ||
| 276 | return 1; | ||
| 277 | } | ||
| 278 | |||
| 279 | fingerprint_file = fopen(tilde_expand(getstroption(CF_FINGERPRINT)), "w"); | ||
| 280 | if (!fingerprint_file) { | ||
| 281 | snprintf (tmpstr, TMPSTRSIZE, "[WARNING] Can't write fingerprint file, %s.", strerror(errno)); | ||
| 282 | writecf(FS_ERR, tmpstr); | ||
| 283 | } else { | ||
| 284 | fputs(fingerprint, fingerprint_file); | ||
| 285 | fclose(fingerprint_file); | ||
| 286 | writecf(FS_SERV, "Stored fingerprint."); | ||
| 287 | } | ||
| 288 | return 0; | ||
| 289 | } | ||
| 290 | 300 | ||
| 291 | /* If verify of x509 chain was requested, do the check here */ | 301 | /* If verify of x509 chain was requested, do the check here */ |
| 292 | if (X509_V_OK == SSL_get_verify_result(sslp)) | 302 | if (X509_V_OK == SSL_get_verify_result(sslp)) |
