Fossil SCM
Merge the ssl-trust-fix branch into trunk.
Commit
0554dbd04a751da15ec98267f4af2f10769a3c36
Parent
c0b6c28d29b2181…
1 file changed
+21
-5
+21
-5
| --- src/http_ssl.c | ||
| +++ src/http_ssl.c | ||
| @@ -184,17 +184,18 @@ | ||
| 184 | 184 | ** Return the number of errors. |
| 185 | 185 | */ |
| 186 | 186 | int ssl_open(void){ |
| 187 | 187 | X509 *cert; |
| 188 | 188 | int hasSavedCertificate = 0; |
| 189 | + int trusted = 0; | |
| 189 | 190 | char *connStr ; |
| 190 | 191 | ssl_global_init(); |
| 191 | 192 | |
| 192 | 193 | /* Get certificate for current server from global config and |
| 193 | 194 | * (if we have it in config) add it to certificate store. |
| 194 | 195 | */ |
| 195 | - cert = ssl_get_certificate(); | |
| 196 | + cert = ssl_get_certificate(&trusted); | |
| 196 | 197 | if ( cert!=NULL ){ |
| 197 | 198 | X509_STORE_add_cert(SSL_CTX_get_cert_store(sslCtx), cert); |
| 198 | 199 | X509_free(cert); |
| 199 | 200 | hasSavedCertificate = 1; |
| 200 | 201 | } |
| @@ -232,11 +233,11 @@ | ||
| 232 | 233 | ssl_set_errmsg("No SSL certificate was presented by the peer"); |
| 233 | 234 | ssl_close(); |
| 234 | 235 | return 1; |
| 235 | 236 | } |
| 236 | 237 | |
| 237 | - if( SSL_get_verify_result(ssl) != X509_V_OK ){ | |
| 238 | + if( trusted<=0 && SSL_get_verify_result(ssl) != X509_V_OK ){ | |
| 238 | 239 | char *desc, *prompt; |
| 239 | 240 | char *warning = ""; |
| 240 | 241 | Blob ans; |
| 241 | 242 | BIO *mem; |
| 242 | 243 | unsigned char md[32]; |
| @@ -278,11 +279,16 @@ | ||
| 278 | 279 | ssl_set_errmsg("SSL certificate declined"); |
| 279 | 280 | ssl_close(); |
| 280 | 281 | return 1; |
| 281 | 282 | } |
| 282 | 283 | if( blob_str(&ans)[0]=='a' ) { |
| 283 | - ssl_save_certificate(cert); | |
| 284 | + Blob ans2; | |
| 285 | + prompt_user("\nSave this certificate as fully trusted [a=always/N]? ", | |
| 286 | + &ans2); | |
| 287 | + trusted = (blob_str(&ans2)[0]=='a'); | |
| 288 | + ssl_save_certificate(cert, trusted); | |
| 289 | + blob_reset(&ans2); | |
| 284 | 290 | } |
| 285 | 291 | blob_reset(&ans); |
| 286 | 292 | } |
| 287 | 293 | |
| 288 | 294 | /* Set the Global.zIpAddr variable to the server we are talking to. |
| @@ -300,11 +306,11 @@ | ||
| 300 | 306 | } |
| 301 | 307 | |
| 302 | 308 | /* |
| 303 | 309 | ** Save certificate to global config. |
| 304 | 310 | */ |
| 305 | -void ssl_save_certificate(X509 *cert){ | |
| 311 | +void ssl_save_certificate(X509 *cert, int trusted){ | |
| 306 | 312 | BIO *mem; |
| 307 | 313 | char *zCert, *zHost; |
| 308 | 314 | |
| 309 | 315 | mem = BIO_new(BIO_s_mem()); |
| 310 | 316 | PEM_write_bio_X509(mem, cert); |
| @@ -311,27 +317,37 @@ | ||
| 311 | 317 | BIO_write(mem, "", 1); /* nul-terminate mem buffer */ |
| 312 | 318 | BIO_get_mem_data(mem, &zCert); |
| 313 | 319 | zHost = mprintf("cert:%s", g.urlName); |
| 314 | 320 | db_set(zHost, zCert, 1); |
| 315 | 321 | free(zHost); |
| 322 | + zHost = mprintf("trusted:%s", g.urlName); | |
| 323 | + db_set_int(zHost, trusted, 1); | |
| 324 | + free(zHost); | |
| 316 | 325 | BIO_free(mem); |
| 317 | 326 | } |
| 318 | 327 | |
| 319 | 328 | /* |
| 320 | 329 | ** Get certificate for g.urlName from global config. |
| 321 | 330 | ** Return NULL if no certificate found. |
| 322 | 331 | */ |
| 323 | -X509 *ssl_get_certificate(void){ | |
| 332 | +X509 *ssl_get_certificate(int *pTrusted){ | |
| 324 | 333 | char *zHost, *zCert; |
| 325 | 334 | BIO *mem; |
| 326 | 335 | X509 *cert; |
| 327 | 336 | |
| 328 | 337 | zHost = mprintf("cert:%s", g.urlName); |
| 329 | 338 | zCert = db_get(zHost, NULL); |
| 330 | 339 | free(zHost); |
| 331 | 340 | if ( zCert==NULL ) |
| 332 | 341 | return NULL; |
| 342 | + | |
| 343 | + if ( pTrusted!=0 ){ | |
| 344 | + zHost = mprintf("trusted:%s", g.urlName); | |
| 345 | + *pTrusted = db_get_int(zHost, 0); | |
| 346 | + free(zHost); | |
| 347 | + } | |
| 348 | + | |
| 333 | 349 | mem = BIO_new(BIO_s_mem()); |
| 334 | 350 | BIO_puts(mem, zCert); |
| 335 | 351 | cert = PEM_read_bio_X509(mem, NULL, 0, NULL); |
| 336 | 352 | free(zCert); |
| 337 | 353 | BIO_free(mem); |
| 338 | 354 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -184,17 +184,18 @@ | |
| 184 | ** Return the number of errors. |
| 185 | */ |
| 186 | int ssl_open(void){ |
| 187 | X509 *cert; |
| 188 | int hasSavedCertificate = 0; |
| 189 | char *connStr ; |
| 190 | ssl_global_init(); |
| 191 | |
| 192 | /* Get certificate for current server from global config and |
| 193 | * (if we have it in config) add it to certificate store. |
| 194 | */ |
| 195 | cert = ssl_get_certificate(); |
| 196 | if ( cert!=NULL ){ |
| 197 | X509_STORE_add_cert(SSL_CTX_get_cert_store(sslCtx), cert); |
| 198 | X509_free(cert); |
| 199 | hasSavedCertificate = 1; |
| 200 | } |
| @@ -232,11 +233,11 @@ | |
| 232 | ssl_set_errmsg("No SSL certificate was presented by the peer"); |
| 233 | ssl_close(); |
| 234 | return 1; |
| 235 | } |
| 236 | |
| 237 | if( SSL_get_verify_result(ssl) != X509_V_OK ){ |
| 238 | char *desc, *prompt; |
| 239 | char *warning = ""; |
| 240 | Blob ans; |
| 241 | BIO *mem; |
| 242 | unsigned char md[32]; |
| @@ -278,11 +279,16 @@ | |
| 278 | ssl_set_errmsg("SSL certificate declined"); |
| 279 | ssl_close(); |
| 280 | return 1; |
| 281 | } |
| 282 | if( blob_str(&ans)[0]=='a' ) { |
| 283 | ssl_save_certificate(cert); |
| 284 | } |
| 285 | blob_reset(&ans); |
| 286 | } |
| 287 | |
| 288 | /* Set the Global.zIpAddr variable to the server we are talking to. |
| @@ -300,11 +306,11 @@ | |
| 300 | } |
| 301 | |
| 302 | /* |
| 303 | ** Save certificate to global config. |
| 304 | */ |
| 305 | void ssl_save_certificate(X509 *cert){ |
| 306 | BIO *mem; |
| 307 | char *zCert, *zHost; |
| 308 | |
| 309 | mem = BIO_new(BIO_s_mem()); |
| 310 | PEM_write_bio_X509(mem, cert); |
| @@ -311,27 +317,37 @@ | |
| 311 | BIO_write(mem, "", 1); /* nul-terminate mem buffer */ |
| 312 | BIO_get_mem_data(mem, &zCert); |
| 313 | zHost = mprintf("cert:%s", g.urlName); |
| 314 | db_set(zHost, zCert, 1); |
| 315 | free(zHost); |
| 316 | BIO_free(mem); |
| 317 | } |
| 318 | |
| 319 | /* |
| 320 | ** Get certificate for g.urlName from global config. |
| 321 | ** Return NULL if no certificate found. |
| 322 | */ |
| 323 | X509 *ssl_get_certificate(void){ |
| 324 | char *zHost, *zCert; |
| 325 | BIO *mem; |
| 326 | X509 *cert; |
| 327 | |
| 328 | zHost = mprintf("cert:%s", g.urlName); |
| 329 | zCert = db_get(zHost, NULL); |
| 330 | free(zHost); |
| 331 | if ( zCert==NULL ) |
| 332 | return NULL; |
| 333 | mem = BIO_new(BIO_s_mem()); |
| 334 | BIO_puts(mem, zCert); |
| 335 | cert = PEM_read_bio_X509(mem, NULL, 0, NULL); |
| 336 | free(zCert); |
| 337 | BIO_free(mem); |
| 338 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -184,17 +184,18 @@ | |
| 184 | ** Return the number of errors. |
| 185 | */ |
| 186 | int ssl_open(void){ |
| 187 | X509 *cert; |
| 188 | int hasSavedCertificate = 0; |
| 189 | int trusted = 0; |
| 190 | char *connStr ; |
| 191 | ssl_global_init(); |
| 192 | |
| 193 | /* Get certificate for current server from global config and |
| 194 | * (if we have it in config) add it to certificate store. |
| 195 | */ |
| 196 | cert = ssl_get_certificate(&trusted); |
| 197 | if ( cert!=NULL ){ |
| 198 | X509_STORE_add_cert(SSL_CTX_get_cert_store(sslCtx), cert); |
| 199 | X509_free(cert); |
| 200 | hasSavedCertificate = 1; |
| 201 | } |
| @@ -232,11 +233,11 @@ | |
| 233 | ssl_set_errmsg("No SSL certificate was presented by the peer"); |
| 234 | ssl_close(); |
| 235 | return 1; |
| 236 | } |
| 237 | |
| 238 | if( trusted<=0 && SSL_get_verify_result(ssl) != X509_V_OK ){ |
| 239 | char *desc, *prompt; |
| 240 | char *warning = ""; |
| 241 | Blob ans; |
| 242 | BIO *mem; |
| 243 | unsigned char md[32]; |
| @@ -278,11 +279,16 @@ | |
| 279 | ssl_set_errmsg("SSL certificate declined"); |
| 280 | ssl_close(); |
| 281 | return 1; |
| 282 | } |
| 283 | if( blob_str(&ans)[0]=='a' ) { |
| 284 | Blob ans2; |
| 285 | prompt_user("\nSave this certificate as fully trusted [a=always/N]? ", |
| 286 | &ans2); |
| 287 | trusted = (blob_str(&ans2)[0]=='a'); |
| 288 | ssl_save_certificate(cert, trusted); |
| 289 | blob_reset(&ans2); |
| 290 | } |
| 291 | blob_reset(&ans); |
| 292 | } |
| 293 | |
| 294 | /* Set the Global.zIpAddr variable to the server we are talking to. |
| @@ -300,11 +306,11 @@ | |
| 306 | } |
| 307 | |
| 308 | /* |
| 309 | ** Save certificate to global config. |
| 310 | */ |
| 311 | void ssl_save_certificate(X509 *cert, int trusted){ |
| 312 | BIO *mem; |
| 313 | char *zCert, *zHost; |
| 314 | |
| 315 | mem = BIO_new(BIO_s_mem()); |
| 316 | PEM_write_bio_X509(mem, cert); |
| @@ -311,27 +317,37 @@ | |
| 317 | BIO_write(mem, "", 1); /* nul-terminate mem buffer */ |
| 318 | BIO_get_mem_data(mem, &zCert); |
| 319 | zHost = mprintf("cert:%s", g.urlName); |
| 320 | db_set(zHost, zCert, 1); |
| 321 | free(zHost); |
| 322 | zHost = mprintf("trusted:%s", g.urlName); |
| 323 | db_set_int(zHost, trusted, 1); |
| 324 | free(zHost); |
| 325 | BIO_free(mem); |
| 326 | } |
| 327 | |
| 328 | /* |
| 329 | ** Get certificate for g.urlName from global config. |
| 330 | ** Return NULL if no certificate found. |
| 331 | */ |
| 332 | X509 *ssl_get_certificate(int *pTrusted){ |
| 333 | char *zHost, *zCert; |
| 334 | BIO *mem; |
| 335 | X509 *cert; |
| 336 | |
| 337 | zHost = mprintf("cert:%s", g.urlName); |
| 338 | zCert = db_get(zHost, NULL); |
| 339 | free(zHost); |
| 340 | if ( zCert==NULL ) |
| 341 | return NULL; |
| 342 | |
| 343 | if ( pTrusted!=0 ){ |
| 344 | zHost = mprintf("trusted:%s", g.urlName); |
| 345 | *pTrusted = db_get_int(zHost, 0); |
| 346 | free(zHost); |
| 347 | } |
| 348 | |
| 349 | mem = BIO_new(BIO_s_mem()); |
| 350 | BIO_puts(mem, zCert); |
| 351 | cert = PEM_read_bio_X509(mem, NULL, 0, NULL); |
| 352 | free(zCert); |
| 353 | BIO_free(mem); |
| 354 |