Fossil SCM
Add a built-in self-signed certificate for use with TLS servers. Add --tls and --ssl options to active TLS for "fossil ui" and "fossil server". Add the "tls-server-cert" setting. Automatically start servers as TLS if the redirect-to-https property is 2.
Commit
7532ffa4e34e3174ae44e8e7b8567ad36f3e915c1d76666f92ebb48b397b4315
Parent
637516c447d6e01…
2 files changed
+142
-10
+13
+142
-10
| --- src/http_ssl.c | ||
| +++ src/http_ssl.c | ||
| @@ -55,10 +55,120 @@ | ||
| 55 | 55 | char *zHost; /* Subject or host name */ |
| 56 | 56 | char *zHash; /* SHA2-256 hash of the cert */ |
| 57 | 57 | } sException; |
| 58 | 58 | static int sslNoCertVerify = 0; /* Do not verify SSL certs */ |
| 59 | 59 | |
| 60 | + | |
| 61 | +/* This is a self-signed cert in the PEM format that can be used when | |
| 62 | +** no other certs are available. | |
| 63 | +*/ | |
| 64 | +static const char sslSelfCert[] = | |
| 65 | +"-----BEGIN CERTIFICATE-----\n" | |
| 66 | +"MIIDMTCCAhkCFGrDmuJkkzWERP/ITBvzwwI2lv0TMA0GCSqGSIb3DQEBCwUAMFQx\n" | |
| 67 | +"CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzESMBAGA1UEBwwJQ2hhcmxvdHRlMRMw\n" | |
| 68 | +"EQYDVQQKDApGb3NzaWwtU0NNMQ8wDQYDVQQDDAZGb3NzaWwwIBcNMjExMjI3MTEz\n" | |
| 69 | +"MTU2WhgPMjEyMTEyMjcxMTMxNTZaMFQxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJO\n" | |
| 70 | +"QzESMBAGA1UEBwwJQ2hhcmxvdHRlMRMwEQYDVQQKDApGb3NzaWwtU0NNMQ8wDQYD\n" | |
| 71 | +"VQQDDAZGb3NzaWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCCbTU2\n" | |
| 72 | +"6GRQHQqLq7vyZ0OxpAxmgfAKCxt6eIz+jBi2ZM/CB5vVXWVh2+SkSiWEA3UZiUqX\n" | |
| 73 | +"xZlzmS/CglZdiwLLDJML8B4OiV72oivFH/vJ7+cbvh1dTxnYiHuww7GfQngPrLfe\n" | |
| 74 | +"fiIYPDk1GTUJHBQ7Ue477F7F8vKuHdVgwktF/JDM6M60aSqlo2D/oysirrb+dlur\n" | |
| 75 | +"Tlv0rjsYOfq6bLAajoL3qi/vek6DNssoywbge4PfbTgS9g7Gcgncbcet5pvaS12J\n" | |
| 76 | +"avhFcd4JU4Ity49Hl9S/C2MfZ1tE53xVggRwKz4FPj65M5uymTdcxtjKXtCxIE1k\n" | |
| 77 | +"KxJxXQh7rIYjm+RTAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFkdtpqcybAzJN8G\n" | |
| 78 | +"+ONuUm5sXNbWta7JGvm8l0BTSBcCUtJA3hn16iJqXA9KmLnaF2denC4EYk+KlVU1\n" | |
| 79 | +"QXxskPJ4jB8A5B05jMijYv0nzCxKhviI8CR7GLEEGKzeg9pbW0+O3vaVehoZtdFX\n" | |
| 80 | +"z3SsCssr9QjCLiApQxMzW1Iv3od2JXeHBwfVMFrWA1VCEUCRs8OSW/VOqDPJLVEi\n" | |
| 81 | +"G6wxc4kN9dLK+5S29q3nzl24/qzXoF8P9Re5KBCbrwaHgy+OEEceq5jkmfGFxXjw\n" | |
| 82 | +"pvVCNry5uAhH5NqbXZampUWqiWtM4eTaIPo7Y2mDA1uWhuWtO6F9PsnFJlQHCnwy\n" | |
| 83 | +"s/TsrXk=\n" | |
| 84 | +"-----END CERTIFICATE-----\n"; | |
| 85 | + | |
| 86 | +/* This is the private-key corresponding to the cert above | |
| 87 | +*/ | |
| 88 | +static const char sslSelfPKey[] = | |
| 89 | +"-----BEGIN PRIVATE KEY-----\n" | |
| 90 | +"MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCCbTU26GRQHQqL\n" | |
| 91 | +"q7vyZ0OxpAxmgfAKCxt6eIz+jBi2ZM/CB5vVXWVh2+SkSiWEA3UZiUqXxZlzmS/C\n" | |
| 92 | +"glZdiwLLDJML8B4OiV72oivFH/vJ7+cbvh1dTxnYiHuww7GfQngPrLfefiIYPDk1\n" | |
| 93 | +"GTUJHBQ7Ue477F7F8vKuHdVgwktF/JDM6M60aSqlo2D/oysirrb+dlurTlv0rjsY\n" | |
| 94 | +"Ofq6bLAajoL3qi/vek6DNssoywbge4PfbTgS9g7Gcgncbcet5pvaS12JavhFcd4J\n" | |
| 95 | +"U4Ity49Hl9S/C2MfZ1tE53xVggRwKz4FPj65M5uymTdcxtjKXtCxIE1kKxJxXQh7\n" | |
| 96 | +"rIYjm+RTAgMBAAECggEANfTH1vc8yIe7HRzmm9lsf8jF+II4s2705y2H5qY+cvYx\n" | |
| 97 | +"nKtZJGOG1X0KkYy7CGoFv5K0cSUl3lS5FVamM/yWIzoIex/Sz2C1EIL2aI5as6ez\n" | |
| 98 | +"jB6SN0/J+XI8+Vt7186/rHxfdIPpxuzjHbxX3HTpScETNWcLrghbrPxakbTPPxwt\n" | |
| 99 | +"+x7QlPmmkFNuMfvkzToFf9NdwL++44TeBPOpvD/Lrw+eyqdth9RJPq9cM96plh9V\n" | |
| 100 | +"HuRqeD8+QNafaXBdSQs3FJK/cDK/vWGKZWIfFVSDbDhwYljkXGijreFjtXQfkkpF\n" | |
| 101 | +"rl1J87/H9Ee7z8fTD2YXQHl+0/rghAVtac3u54dpQQKBgQC2XG3OEeMrOp9dNkUd\n" | |
| 102 | +"F8VffUg0ecwG+9L3LCe7U71K0kPmXjV6xNnuYcNQu84kptc5vI8wD23p29LaxdNc\n" | |
| 103 | +"9m0lcw06/YYBOPkNphcHkINYZTvVJF10mL3isymzMaTtwDkZUkOjL1B+MTiFT/qp\n" | |
| 104 | +"ARKrTYGJ4HxY7+tUkI5pUmg4PQKBgQC3GA4d1Rz3Pb/RRpcsZgWknKsKhoN36mSn\n" | |
| 105 | +"xFJ3wPBvVv2B1ltTMzh/+the0ty6clzMrvoLERzRcheDsNrc/j/TUVG8sVdBYJwX\n" | |
| 106 | +"tMZyFW4NVMOErT/1ukh6jBqIMBo6NJL3EV/AKj0yniksgKOr0/AAduAccnGST8Jd\n" | |
| 107 | +"SHOdjwvHzwKBgGZBq/zqgNTDuYseHGE07CMgcDWkumiMGv8ozlq3mSR0hUiPOTPP\n" | |
| 108 | +"YFjQjyIdPXnF6FfiyPPtIvgIoNK2LVAqiod+XUPf152l4dnqcW13dn9BvOxGyPTR\n" | |
| 109 | +"lWCikFaAFviOWjY9r9m4dU1dslDmySqthFd0TZgPvgps9ivkJ0cdw30NAoGAMC/E\n" | |
| 110 | +"h1VvKiK2OP27C5ROJ+STn1GHiCfIFd81VQ8SODtMvL8NifgRBp2eFFaqgOdYRQZI\n" | |
| 111 | +"CGGYlAbS6XXCJCdF5Peh62dA75PdgN+y2pOJQzjrvB9cle9Q4++7i9wdCvSLOTr5\n" | |
| 112 | +"WDnFoWy+qVexu6crovOmR9ZWzYrwPFy1EOJ010ECgYBl7Q+jmjOSqsVwhFZ0U7LG\n" | |
| 113 | +"diN+vXhWfn1wfOWd8u79oaqU/Oy7xyKW2p3H5z2KFrBM/vib53Lh4EwFZjcX+jVG\n" | |
| 114 | +"krAmbL+M/hP7z3TD2UbESAzR/c6l7FU45xN84Lsz5npkR8H/uAHuqLgb9e430Mjx\n" | |
| 115 | +"YNMwdb8rChHHChNZu6zuxw==\n" | |
| 116 | +"-----END PRIVATE KEY-----\n"; | |
| 117 | + | |
| 118 | +/* | |
| 119 | +** Read a PEM certificate from memory and push it into an SSL_CTX. | |
| 120 | +** Return the number of errors. | |
| 121 | +*/ | |
| 122 | +static int sslctx_use_cert_from_mem( | |
| 123 | + SSL_CTX *ctx, | |
| 124 | + const char *pData, | |
| 125 | + int nData | |
| 126 | +){ | |
| 127 | + BIO *in; | |
| 128 | + int rc = 1; | |
| 129 | + X509 *x = 0; | |
| 130 | + X509 *cert = 0; | |
| 131 | + | |
| 132 | + in = BIO_new_mem_buf(pData, nData); | |
| 133 | + if( in==0 ) goto end_of_ucfm; | |
| 134 | + // x = X509_new_ex(ctx->libctx, ctx->propq); | |
| 135 | + x = X509_new(); | |
| 136 | + if( x==0 ) goto end_of_ucfm; | |
| 137 | + cert = PEM_read_bio_X509(in, &x, 0, 0); | |
| 138 | + if( cert==0 ) goto end_of_ucfm; | |
| 139 | + rc = SSL_CTX_use_certificate(ctx, x)<=0; | |
| 140 | +end_of_ucfm: | |
| 141 | + X509_free(x); | |
| 142 | + BIO_free(in); | |
| 143 | + return rc; | |
| 144 | +} | |
| 145 | + | |
| 146 | +/* | |
| 147 | +** Read a PEM private key from memory and add it to an SSL_CTX. | |
| 148 | +** Return the number of errors. | |
| 149 | +*/ | |
| 150 | +static int sslctx_use_pkey_from_mem( | |
| 151 | + SSL_CTX *ctx, | |
| 152 | + const char *pData, | |
| 153 | + int nData | |
| 154 | +){ | |
| 155 | + int rc = 1; | |
| 156 | + BIO *in; | |
| 157 | + EVP_PKEY *pkey = 0; | |
| 158 | + | |
| 159 | + in = BIO_new_mem_buf(pData, nData); | |
| 160 | + if( in==0 ) goto end_of_upkfm; | |
| 161 | + pkey = PEM_read_bio_PrivateKey(in, 0, 0, 0); | |
| 162 | + if( pkey==0 ) goto end_of_upkfm; | |
| 163 | + rc = SSL_CTX_use_PrivateKey(ctx, pkey)<=0; | |
| 164 | + EVP_PKEY_free(pkey); | |
| 165 | +end_of_upkfm: | |
| 166 | + BIO_free(in); | |
| 167 | + return rc; | |
| 168 | +} | |
| 169 | + | |
| 60 | 170 | /* |
| 61 | 171 | ** Clear the SSL error message |
| 62 | 172 | */ |
| 63 | 173 | static void ssl_clear_errmsg(void){ |
| 64 | 174 | free(sslErrMsg); |
| @@ -581,31 +691,53 @@ | ||
| 581 | 691 | /* |
| 582 | 692 | ** Initialize the SSL library so that it is able to handle |
| 583 | 693 | ** server-side connections. Invoke fossil_fatal() if there are |
| 584 | 694 | ** any problems. |
| 585 | 695 | ** |
| 586 | -** zKeyFile may be NULL, in which case zCertFile will contain both | |
| 587 | -** the private key and the cert. | |
| 696 | +** If zKeyFile and zCertFile are not NULL, then they are the names | |
| 697 | +** of disk files that hold the certificate and private-key for the | |
| 698 | +** server. If zCertFile is not NULL but zKeyFile is NULL, then | |
| 699 | +** zCertFile is assumed to be a concatenation of the certificate and | |
| 700 | +** the private-key in the PEM format. | |
| 701 | +** | |
| 702 | +** If zCertFile is NULL, then "tls-server-cert" setting is consulted | |
| 703 | +** to get the certificate and private-key (concatenated together, in | |
| 704 | +** the PEM format). If there is no tls-server-cert setting, then | |
| 705 | +** a built-in self-signed cert is used. | |
| 588 | 706 | */ |
| 589 | 707 | void ssl_init_server(const char *zCertFile, const char *zKeyFile){ |
| 590 | 708 | if( sslIsInit==0 ){ |
| 709 | + const char *zTlsCert; | |
| 591 | 710 | SSL_library_init(); |
| 592 | 711 | SSL_load_error_strings(); |
| 593 | 712 | OpenSSL_add_all_algorithms(); |
| 594 | 713 | sslCtx = SSL_CTX_new(SSLv23_server_method()); |
| 595 | 714 | if( sslCtx==0 ){ |
| 596 | 715 | ERR_print_errors_fp(stderr); |
| 597 | 716 | fossil_fatal("Error initializing the SSL server"); |
| 598 | 717 | } |
| 599 | - if( SSL_CTX_use_certificate_file(sslCtx, zCertFile, SSL_FILETYPE_PEM)<=0 ){ | |
| 600 | - ERR_print_errors_fp(stderr); | |
| 601 | - fossil_fatal("Error loading CERT file \"%s\"", zCertFile); | |
| 602 | - } | |
| 603 | - if( zKeyFile==0 ) zKeyFile = zCertFile; | |
| 604 | - if( SSL_CTX_use_PrivateKey_file(sslCtx, zKeyFile, SSL_FILETYPE_PEM)<=0 ){ | |
| 605 | - ERR_print_errors_fp(stderr); | |
| 606 | - fossil_fatal("Error loading PRIVATE KEY from file \"%s\"", zKeyFile); | |
| 718 | + if( zCertFile && zCertFile[0] ){ | |
| 719 | + if( SSL_CTX_use_certificate_file(sslCtx,zCertFile,SSL_FILETYPE_PEM)<=0 ){ | |
| 720 | + ERR_print_errors_fp(stderr); | |
| 721 | + fossil_fatal("Error loading CERT file \"%s\"", zCertFile); | |
| 722 | + } | |
| 723 | + if( zKeyFile==0 ) zKeyFile = zCertFile; | |
| 724 | + if( SSL_CTX_use_PrivateKey_file(sslCtx, zKeyFile, SSL_FILETYPE_PEM)<=0 ){ | |
| 725 | + ERR_print_errors_fp(stderr); | |
| 726 | + fossil_fatal("Error loading PRIVATE KEY from file \"%s\"", zKeyFile); | |
| 727 | + } | |
| 728 | + }else | |
| 729 | + if( (zTlsCert = db_get("tls-server-cert",0))!=0 ){ | |
| 730 | + if( sslctx_use_cert_from_mem(sslCtx, zTlsCert, -1) | |
| 731 | + || sslctx_use_pkey_from_mem(sslCtx, zTlsCert, -1) | |
| 732 | + ){ | |
| 733 | + fossil_fatal("Error loading the CERT from the" | |
| 734 | + " 'tls-server-cert' setting"); | |
| 735 | + } | |
| 736 | + }else if( sslctx_use_cert_from_mem(sslCtx, sslSelfCert, -1) | |
| 737 | + || sslctx_use_pkey_from_mem(sslCtx, sslSelfPKey, -1) ){ | |
| 738 | + fossil_fatal("Error loading self-signed CERT"); | |
| 607 | 739 | } |
| 608 | 740 | if( !SSL_CTX_check_private_key(sslCtx) ){ |
| 609 | 741 | fossil_fatal("PRIVATE KEY \"%s\" does not match CERT \"%s\"", |
| 610 | 742 | zKeyFile, zCertFile); |
| 611 | 743 | } |
| 612 | 744 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -55,10 +55,120 @@ | |
| 55 | char *zHost; /* Subject or host name */ |
| 56 | char *zHash; /* SHA2-256 hash of the cert */ |
| 57 | } sException; |
| 58 | static int sslNoCertVerify = 0; /* Do not verify SSL certs */ |
| 59 | |
| 60 | /* |
| 61 | ** Clear the SSL error message |
| 62 | */ |
| 63 | static void ssl_clear_errmsg(void){ |
| 64 | free(sslErrMsg); |
| @@ -581,31 +691,53 @@ | |
| 581 | /* |
| 582 | ** Initialize the SSL library so that it is able to handle |
| 583 | ** server-side connections. Invoke fossil_fatal() if there are |
| 584 | ** any problems. |
| 585 | ** |
| 586 | ** zKeyFile may be NULL, in which case zCertFile will contain both |
| 587 | ** the private key and the cert. |
| 588 | */ |
| 589 | void ssl_init_server(const char *zCertFile, const char *zKeyFile){ |
| 590 | if( sslIsInit==0 ){ |
| 591 | SSL_library_init(); |
| 592 | SSL_load_error_strings(); |
| 593 | OpenSSL_add_all_algorithms(); |
| 594 | sslCtx = SSL_CTX_new(SSLv23_server_method()); |
| 595 | if( sslCtx==0 ){ |
| 596 | ERR_print_errors_fp(stderr); |
| 597 | fossil_fatal("Error initializing the SSL server"); |
| 598 | } |
| 599 | if( SSL_CTX_use_certificate_file(sslCtx, zCertFile, SSL_FILETYPE_PEM)<=0 ){ |
| 600 | ERR_print_errors_fp(stderr); |
| 601 | fossil_fatal("Error loading CERT file \"%s\"", zCertFile); |
| 602 | } |
| 603 | if( zKeyFile==0 ) zKeyFile = zCertFile; |
| 604 | if( SSL_CTX_use_PrivateKey_file(sslCtx, zKeyFile, SSL_FILETYPE_PEM)<=0 ){ |
| 605 | ERR_print_errors_fp(stderr); |
| 606 | fossil_fatal("Error loading PRIVATE KEY from file \"%s\"", zKeyFile); |
| 607 | } |
| 608 | if( !SSL_CTX_check_private_key(sslCtx) ){ |
| 609 | fossil_fatal("PRIVATE KEY \"%s\" does not match CERT \"%s\"", |
| 610 | zKeyFile, zCertFile); |
| 611 | } |
| 612 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -55,10 +55,120 @@ | |
| 55 | char *zHost; /* Subject or host name */ |
| 56 | char *zHash; /* SHA2-256 hash of the cert */ |
| 57 | } sException; |
| 58 | static int sslNoCertVerify = 0; /* Do not verify SSL certs */ |
| 59 | |
| 60 | |
| 61 | /* This is a self-signed cert in the PEM format that can be used when |
| 62 | ** no other certs are available. |
| 63 | */ |
| 64 | static const char sslSelfCert[] = |
| 65 | "-----BEGIN CERTIFICATE-----\n" |
| 66 | "MIIDMTCCAhkCFGrDmuJkkzWERP/ITBvzwwI2lv0TMA0GCSqGSIb3DQEBCwUAMFQx\n" |
| 67 | "CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJOQzESMBAGA1UEBwwJQ2hhcmxvdHRlMRMw\n" |
| 68 | "EQYDVQQKDApGb3NzaWwtU0NNMQ8wDQYDVQQDDAZGb3NzaWwwIBcNMjExMjI3MTEz\n" |
| 69 | "MTU2WhgPMjEyMTEyMjcxMTMxNTZaMFQxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJO\n" |
| 70 | "QzESMBAGA1UEBwwJQ2hhcmxvdHRlMRMwEQYDVQQKDApGb3NzaWwtU0NNMQ8wDQYD\n" |
| 71 | "VQQDDAZGb3NzaWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCCbTU2\n" |
| 72 | "6GRQHQqLq7vyZ0OxpAxmgfAKCxt6eIz+jBi2ZM/CB5vVXWVh2+SkSiWEA3UZiUqX\n" |
| 73 | "xZlzmS/CglZdiwLLDJML8B4OiV72oivFH/vJ7+cbvh1dTxnYiHuww7GfQngPrLfe\n" |
| 74 | "fiIYPDk1GTUJHBQ7Ue477F7F8vKuHdVgwktF/JDM6M60aSqlo2D/oysirrb+dlur\n" |
| 75 | "Tlv0rjsYOfq6bLAajoL3qi/vek6DNssoywbge4PfbTgS9g7Gcgncbcet5pvaS12J\n" |
| 76 | "avhFcd4JU4Ity49Hl9S/C2MfZ1tE53xVggRwKz4FPj65M5uymTdcxtjKXtCxIE1k\n" |
| 77 | "KxJxXQh7rIYjm+RTAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFkdtpqcybAzJN8G\n" |
| 78 | "+ONuUm5sXNbWta7JGvm8l0BTSBcCUtJA3hn16iJqXA9KmLnaF2denC4EYk+KlVU1\n" |
| 79 | "QXxskPJ4jB8A5B05jMijYv0nzCxKhviI8CR7GLEEGKzeg9pbW0+O3vaVehoZtdFX\n" |
| 80 | "z3SsCssr9QjCLiApQxMzW1Iv3od2JXeHBwfVMFrWA1VCEUCRs8OSW/VOqDPJLVEi\n" |
| 81 | "G6wxc4kN9dLK+5S29q3nzl24/qzXoF8P9Re5KBCbrwaHgy+OEEceq5jkmfGFxXjw\n" |
| 82 | "pvVCNry5uAhH5NqbXZampUWqiWtM4eTaIPo7Y2mDA1uWhuWtO6F9PsnFJlQHCnwy\n" |
| 83 | "s/TsrXk=\n" |
| 84 | "-----END CERTIFICATE-----\n"; |
| 85 | |
| 86 | /* This is the private-key corresponding to the cert above |
| 87 | */ |
| 88 | static const char sslSelfPKey[] = |
| 89 | "-----BEGIN PRIVATE KEY-----\n" |
| 90 | "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCCbTU26GRQHQqL\n" |
| 91 | "q7vyZ0OxpAxmgfAKCxt6eIz+jBi2ZM/CB5vVXWVh2+SkSiWEA3UZiUqXxZlzmS/C\n" |
| 92 | "glZdiwLLDJML8B4OiV72oivFH/vJ7+cbvh1dTxnYiHuww7GfQngPrLfefiIYPDk1\n" |
| 93 | "GTUJHBQ7Ue477F7F8vKuHdVgwktF/JDM6M60aSqlo2D/oysirrb+dlurTlv0rjsY\n" |
| 94 | "Ofq6bLAajoL3qi/vek6DNssoywbge4PfbTgS9g7Gcgncbcet5pvaS12JavhFcd4J\n" |
| 95 | "U4Ity49Hl9S/C2MfZ1tE53xVggRwKz4FPj65M5uymTdcxtjKXtCxIE1kKxJxXQh7\n" |
| 96 | "rIYjm+RTAgMBAAECggEANfTH1vc8yIe7HRzmm9lsf8jF+II4s2705y2H5qY+cvYx\n" |
| 97 | "nKtZJGOG1X0KkYy7CGoFv5K0cSUl3lS5FVamM/yWIzoIex/Sz2C1EIL2aI5as6ez\n" |
| 98 | "jB6SN0/J+XI8+Vt7186/rHxfdIPpxuzjHbxX3HTpScETNWcLrghbrPxakbTPPxwt\n" |
| 99 | "+x7QlPmmkFNuMfvkzToFf9NdwL++44TeBPOpvD/Lrw+eyqdth9RJPq9cM96plh9V\n" |
| 100 | "HuRqeD8+QNafaXBdSQs3FJK/cDK/vWGKZWIfFVSDbDhwYljkXGijreFjtXQfkkpF\n" |
| 101 | "rl1J87/H9Ee7z8fTD2YXQHl+0/rghAVtac3u54dpQQKBgQC2XG3OEeMrOp9dNkUd\n" |
| 102 | "F8VffUg0ecwG+9L3LCe7U71K0kPmXjV6xNnuYcNQu84kptc5vI8wD23p29LaxdNc\n" |
| 103 | "9m0lcw06/YYBOPkNphcHkINYZTvVJF10mL3isymzMaTtwDkZUkOjL1B+MTiFT/qp\n" |
| 104 | "ARKrTYGJ4HxY7+tUkI5pUmg4PQKBgQC3GA4d1Rz3Pb/RRpcsZgWknKsKhoN36mSn\n" |
| 105 | "xFJ3wPBvVv2B1ltTMzh/+the0ty6clzMrvoLERzRcheDsNrc/j/TUVG8sVdBYJwX\n" |
| 106 | "tMZyFW4NVMOErT/1ukh6jBqIMBo6NJL3EV/AKj0yniksgKOr0/AAduAccnGST8Jd\n" |
| 107 | "SHOdjwvHzwKBgGZBq/zqgNTDuYseHGE07CMgcDWkumiMGv8ozlq3mSR0hUiPOTPP\n" |
| 108 | "YFjQjyIdPXnF6FfiyPPtIvgIoNK2LVAqiod+XUPf152l4dnqcW13dn9BvOxGyPTR\n" |
| 109 | "lWCikFaAFviOWjY9r9m4dU1dslDmySqthFd0TZgPvgps9ivkJ0cdw30NAoGAMC/E\n" |
| 110 | "h1VvKiK2OP27C5ROJ+STn1GHiCfIFd81VQ8SODtMvL8NifgRBp2eFFaqgOdYRQZI\n" |
| 111 | "CGGYlAbS6XXCJCdF5Peh62dA75PdgN+y2pOJQzjrvB9cle9Q4++7i9wdCvSLOTr5\n" |
| 112 | "WDnFoWy+qVexu6crovOmR9ZWzYrwPFy1EOJ010ECgYBl7Q+jmjOSqsVwhFZ0U7LG\n" |
| 113 | "diN+vXhWfn1wfOWd8u79oaqU/Oy7xyKW2p3H5z2KFrBM/vib53Lh4EwFZjcX+jVG\n" |
| 114 | "krAmbL+M/hP7z3TD2UbESAzR/c6l7FU45xN84Lsz5npkR8H/uAHuqLgb9e430Mjx\n" |
| 115 | "YNMwdb8rChHHChNZu6zuxw==\n" |
| 116 | "-----END PRIVATE KEY-----\n"; |
| 117 | |
| 118 | /* |
| 119 | ** Read a PEM certificate from memory and push it into an SSL_CTX. |
| 120 | ** Return the number of errors. |
| 121 | */ |
| 122 | static int sslctx_use_cert_from_mem( |
| 123 | SSL_CTX *ctx, |
| 124 | const char *pData, |
| 125 | int nData |
| 126 | ){ |
| 127 | BIO *in; |
| 128 | int rc = 1; |
| 129 | X509 *x = 0; |
| 130 | X509 *cert = 0; |
| 131 | |
| 132 | in = BIO_new_mem_buf(pData, nData); |
| 133 | if( in==0 ) goto end_of_ucfm; |
| 134 | // x = X509_new_ex(ctx->libctx, ctx->propq); |
| 135 | x = X509_new(); |
| 136 | if( x==0 ) goto end_of_ucfm; |
| 137 | cert = PEM_read_bio_X509(in, &x, 0, 0); |
| 138 | if( cert==0 ) goto end_of_ucfm; |
| 139 | rc = SSL_CTX_use_certificate(ctx, x)<=0; |
| 140 | end_of_ucfm: |
| 141 | X509_free(x); |
| 142 | BIO_free(in); |
| 143 | return rc; |
| 144 | } |
| 145 | |
| 146 | /* |
| 147 | ** Read a PEM private key from memory and add it to an SSL_CTX. |
| 148 | ** Return the number of errors. |
| 149 | */ |
| 150 | static int sslctx_use_pkey_from_mem( |
| 151 | SSL_CTX *ctx, |
| 152 | const char *pData, |
| 153 | int nData |
| 154 | ){ |
| 155 | int rc = 1; |
| 156 | BIO *in; |
| 157 | EVP_PKEY *pkey = 0; |
| 158 | |
| 159 | in = BIO_new_mem_buf(pData, nData); |
| 160 | if( in==0 ) goto end_of_upkfm; |
| 161 | pkey = PEM_read_bio_PrivateKey(in, 0, 0, 0); |
| 162 | if( pkey==0 ) goto end_of_upkfm; |
| 163 | rc = SSL_CTX_use_PrivateKey(ctx, pkey)<=0; |
| 164 | EVP_PKEY_free(pkey); |
| 165 | end_of_upkfm: |
| 166 | BIO_free(in); |
| 167 | return rc; |
| 168 | } |
| 169 | |
| 170 | /* |
| 171 | ** Clear the SSL error message |
| 172 | */ |
| 173 | static void ssl_clear_errmsg(void){ |
| 174 | free(sslErrMsg); |
| @@ -581,31 +691,53 @@ | |
| 691 | /* |
| 692 | ** Initialize the SSL library so that it is able to handle |
| 693 | ** server-side connections. Invoke fossil_fatal() if there are |
| 694 | ** any problems. |
| 695 | ** |
| 696 | ** If zKeyFile and zCertFile are not NULL, then they are the names |
| 697 | ** of disk files that hold the certificate and private-key for the |
| 698 | ** server. If zCertFile is not NULL but zKeyFile is NULL, then |
| 699 | ** zCertFile is assumed to be a concatenation of the certificate and |
| 700 | ** the private-key in the PEM format. |
| 701 | ** |
| 702 | ** If zCertFile is NULL, then "tls-server-cert" setting is consulted |
| 703 | ** to get the certificate and private-key (concatenated together, in |
| 704 | ** the PEM format). If there is no tls-server-cert setting, then |
| 705 | ** a built-in self-signed cert is used. |
| 706 | */ |
| 707 | void ssl_init_server(const char *zCertFile, const char *zKeyFile){ |
| 708 | if( sslIsInit==0 ){ |
| 709 | const char *zTlsCert; |
| 710 | SSL_library_init(); |
| 711 | SSL_load_error_strings(); |
| 712 | OpenSSL_add_all_algorithms(); |
| 713 | sslCtx = SSL_CTX_new(SSLv23_server_method()); |
| 714 | if( sslCtx==0 ){ |
| 715 | ERR_print_errors_fp(stderr); |
| 716 | fossil_fatal("Error initializing the SSL server"); |
| 717 | } |
| 718 | if( zCertFile && zCertFile[0] ){ |
| 719 | if( SSL_CTX_use_certificate_file(sslCtx,zCertFile,SSL_FILETYPE_PEM)<=0 ){ |
| 720 | ERR_print_errors_fp(stderr); |
| 721 | fossil_fatal("Error loading CERT file \"%s\"", zCertFile); |
| 722 | } |
| 723 | if( zKeyFile==0 ) zKeyFile = zCertFile; |
| 724 | if( SSL_CTX_use_PrivateKey_file(sslCtx, zKeyFile, SSL_FILETYPE_PEM)<=0 ){ |
| 725 | ERR_print_errors_fp(stderr); |
| 726 | fossil_fatal("Error loading PRIVATE KEY from file \"%s\"", zKeyFile); |
| 727 | } |
| 728 | }else |
| 729 | if( (zTlsCert = db_get("tls-server-cert",0))!=0 ){ |
| 730 | if( sslctx_use_cert_from_mem(sslCtx, zTlsCert, -1) |
| 731 | || sslctx_use_pkey_from_mem(sslCtx, zTlsCert, -1) |
| 732 | ){ |
| 733 | fossil_fatal("Error loading the CERT from the" |
| 734 | " 'tls-server-cert' setting"); |
| 735 | } |
| 736 | }else if( sslctx_use_cert_from_mem(sslCtx, sslSelfCert, -1) |
| 737 | || sslctx_use_pkey_from_mem(sslCtx, sslSelfPKey, -1) ){ |
| 738 | fossil_fatal("Error loading self-signed CERT"); |
| 739 | } |
| 740 | if( !SSL_CTX_check_private_key(sslCtx) ){ |
| 741 | fossil_fatal("PRIVATE KEY \"%s\" does not match CERT \"%s\"", |
| 742 | zKeyFile, zCertFile); |
| 743 | } |
| 744 |
+13
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -2848,10 +2848,20 @@ | ||
| 2848 | 2848 | zCertFile = find_option("tls-cert-file",0,1); |
| 2849 | 2849 | if( zCertFile ){ |
| 2850 | 2850 | g.httpUseSSL = 1; |
| 2851 | 2851 | ssl_init_server(zCertFile, zCertFile); |
| 2852 | 2852 | } |
| 2853 | + if( find_option("tls",0,0)!=0 || find_option("ssl",0,0)!=0 ){ | |
| 2854 | + g.httpUseSSL = 1; | |
| 2855 | + ssl_init_server(0,0); | |
| 2856 | + } | |
| 2857 | +#if !defined(_WIN32) | |
| 2858 | + if( db_get_int("redirect-to-https",0)==2 ){ | |
| 2859 | + g.httpUseSSL = 1; | |
| 2860 | + ssl_init_server(0,0); | |
| 2861 | + } | |
| 2862 | +#endif | |
| 2853 | 2863 | #endif |
| 2854 | 2864 | } |
| 2855 | 2865 | |
| 2856 | 2866 | /* |
| 2857 | 2867 | ** COMMAND: server* |
| @@ -2948,11 +2958,14 @@ | ||
| 2948 | 2958 | ** --page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci" |
| 2949 | 2959 | ** -P|--port TCPPORT listen to request on port TCPPORT |
| 2950 | 2960 | ** --repolist If REPOSITORY is dir, URL "/" lists repos. |
| 2951 | 2961 | ** --scgi Accept SCGI rather than HTTP |
| 2952 | 2962 | ** --skin LABEL Use override skin LABEL |
| 2963 | +** --ssl Use TLS (HTTPS) encryption. Alias for --tls | |
| 2953 | 2964 | ** --th-trace trace TH1 execution (for debugging purposes) |
| 2965 | +** --tls Use TLS (HTTPS) encryption. | |
| 2966 | +** --tls-cert-file FN Read the TLS certificate and private key from FN | |
| 2954 | 2967 | ** --usepidkey Use saved encryption key from parent process. This is |
| 2955 | 2968 | ** only necessary when using SEE on Windows. |
| 2956 | 2969 | ** |
| 2957 | 2970 | ** See also: [[cgi]], [[http]], [[winsrv]] |
| 2958 | 2971 | */ |
| 2959 | 2972 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -2848,10 +2848,20 @@ | |
| 2848 | zCertFile = find_option("tls-cert-file",0,1); |
| 2849 | if( zCertFile ){ |
| 2850 | g.httpUseSSL = 1; |
| 2851 | ssl_init_server(zCertFile, zCertFile); |
| 2852 | } |
| 2853 | #endif |
| 2854 | } |
| 2855 | |
| 2856 | /* |
| 2857 | ** COMMAND: server* |
| @@ -2948,11 +2958,14 @@ | |
| 2948 | ** --page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci" |
| 2949 | ** -P|--port TCPPORT listen to request on port TCPPORT |
| 2950 | ** --repolist If REPOSITORY is dir, URL "/" lists repos. |
| 2951 | ** --scgi Accept SCGI rather than HTTP |
| 2952 | ** --skin LABEL Use override skin LABEL |
| 2953 | ** --th-trace trace TH1 execution (for debugging purposes) |
| 2954 | ** --usepidkey Use saved encryption key from parent process. This is |
| 2955 | ** only necessary when using SEE on Windows. |
| 2956 | ** |
| 2957 | ** See also: [[cgi]], [[http]], [[winsrv]] |
| 2958 | */ |
| 2959 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -2848,10 +2848,20 @@ | |
| 2848 | zCertFile = find_option("tls-cert-file",0,1); |
| 2849 | if( zCertFile ){ |
| 2850 | g.httpUseSSL = 1; |
| 2851 | ssl_init_server(zCertFile, zCertFile); |
| 2852 | } |
| 2853 | if( find_option("tls",0,0)!=0 || find_option("ssl",0,0)!=0 ){ |
| 2854 | g.httpUseSSL = 1; |
| 2855 | ssl_init_server(0,0); |
| 2856 | } |
| 2857 | #if !defined(_WIN32) |
| 2858 | if( db_get_int("redirect-to-https",0)==2 ){ |
| 2859 | g.httpUseSSL = 1; |
| 2860 | ssl_init_server(0,0); |
| 2861 | } |
| 2862 | #endif |
| 2863 | #endif |
| 2864 | } |
| 2865 | |
| 2866 | /* |
| 2867 | ** COMMAND: server* |
| @@ -2948,11 +2958,14 @@ | |
| 2958 | ** --page PAGE Start "ui" on PAGE. ex: --page "timeline?y=ci" |
| 2959 | ** -P|--port TCPPORT listen to request on port TCPPORT |
| 2960 | ** --repolist If REPOSITORY is dir, URL "/" lists repos. |
| 2961 | ** --scgi Accept SCGI rather than HTTP |
| 2962 | ** --skin LABEL Use override skin LABEL |
| 2963 | ** --ssl Use TLS (HTTPS) encryption. Alias for --tls |
| 2964 | ** --th-trace trace TH1 execution (for debugging purposes) |
| 2965 | ** --tls Use TLS (HTTPS) encryption. |
| 2966 | ** --tls-cert-file FN Read the TLS certificate and private key from FN |
| 2967 | ** --usepidkey Use saved encryption key from parent process. This is |
| 2968 | ** only necessary when using SEE on Windows. |
| 2969 | ** |
| 2970 | ** See also: [[cgi]], [[http]], [[winsrv]] |
| 2971 | */ |
| 2972 |