LCOV - code coverage report
Current view: top level - source4/lib/tls - tlscert.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 60 75 80.0 %
Date: 2024-04-21 15:09:00 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    auto-generate self signed TLS certificates
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2005
       7             :    
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             :    
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             :    
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "lib/util/util_file.h"
      24             : #include "lib/tls/tls.h"
      25             : 
      26             : #include <gnutls/gnutls.h>
      27             : #include <gnutls/x509.h>
      28             : 
      29             : #define ORGANISATION_NAME "Samba Administration"
      30             : #define CA_NAME           "Samba - temporary autogenerated CA certificate"
      31             : #define UNIT_NAME         "Samba - temporary autogenerated HOST certificate"
      32             : #define LIFETIME          700*24*60*60
      33             : 
      34             : /* FIPS140-2 only allows 2048 or 3072 prime sizes. */
      35             : #define RSA_BITS gnutls_fips140_mode_enabled() ? 3072 : 4096
      36             : 
      37             : /* 
      38             :    auto-generate a set of self signed certificates
      39             : */
      40          33 : void tls_cert_generate(TALLOC_CTX *mem_ctx, 
      41             :                        const char *hostname, 
      42             :                        const char *keyfile, const char *certfile,
      43             :                        const char *cafile)
      44             : {
      45           0 :         gnutls_x509_crt_t cacrt, crt;
      46           0 :         gnutls_x509_privkey_t key, cakey;
      47          33 :         uint32_t serial = (uint32_t)time(NULL);
      48           0 :         unsigned char keyid[100];
      49           0 :         char buf[4096];
      50           0 :         size_t bufsize;
      51          33 :         size_t keyidsize = sizeof(keyid);
      52          33 :         time_t activation = time(NULL), expiry = activation + LIFETIME;
      53           0 :         int ret;
      54             : 
      55          33 :         if (file_exist(keyfile) || file_exist(certfile) || file_exist(cafile)) {
      56           0 :                 DEBUG(0,("TLS autogeneration skipped - some TLS files already exist\n"));
      57          33 :                 return;
      58             :         }
      59             : 
      60             : #define TLSCHECK(call) do { \
      61             :         ret = call; \
      62             :         if (ret < 0) { \
      63             :                 DEBUG(0,("TLS %s - %s\n", #call, gnutls_strerror(ret))); \
      64             :                 goto failed; \
      65             :         } \
      66             : } while (0)
      67             : 
      68          33 :         DEBUG(0,("Attempting to autogenerate TLS self-signed keys for https for hostname '%s'\n", 
      69             :                  hostname));
      70             : 
      71          33 :         DEBUG(3,("Generating private key\n"));
      72          33 :         TLSCHECK(gnutls_x509_privkey_init(&key));
      73          33 :         TLSCHECK(gnutls_x509_privkey_generate(key,   GNUTLS_PK_RSA, RSA_BITS, 0));
      74             : 
      75          33 :         DEBUG(3,("Generating CA private key\n"));
      76          33 :         TLSCHECK(gnutls_x509_privkey_init(&cakey));
      77          33 :         TLSCHECK(gnutls_x509_privkey_generate(cakey, GNUTLS_PK_RSA, RSA_BITS, 0));
      78             : 
      79          33 :         DEBUG(3,("Generating CA certificate\n"));
      80          33 :         TLSCHECK(gnutls_x509_crt_init(&cacrt));
      81          33 :         TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, 
      82             :                                       GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
      83             :                                       ORGANISATION_NAME, strlen(ORGANISATION_NAME)));
      84          33 :         TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, 
      85             :                                       GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0,
      86             :                                       CA_NAME, strlen(CA_NAME)));
      87          33 :         TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt,
      88             :                                       GNUTLS_OID_X520_COMMON_NAME, 0,
      89             :                                       hostname, strlen(hostname)));
      90          33 :         TLSCHECK(gnutls_x509_crt_set_key(cacrt, cakey));
      91          33 :         TLSCHECK(gnutls_x509_crt_set_serial(cacrt, &serial, sizeof(serial)));
      92          33 :         TLSCHECK(gnutls_x509_crt_set_activation_time(cacrt, activation));
      93          33 :         TLSCHECK(gnutls_x509_crt_set_expiration_time(cacrt, expiry));
      94          33 :         TLSCHECK(gnutls_x509_crt_set_ca_status(cacrt, 1));
      95          33 :         TLSCHECK(gnutls_x509_crt_set_key_usage(cacrt, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN));
      96          33 :         TLSCHECK(gnutls_x509_crt_set_version(cacrt, 3));
      97          33 :         TLSCHECK(gnutls_x509_crt_get_key_id(cacrt, 0, keyid, &keyidsize));
      98          33 :         TLSCHECK(gnutls_x509_crt_set_subject_key_id(cacrt, keyid, keyidsize));
      99          33 :         TLSCHECK(gnutls_x509_crt_sign2(cacrt, cacrt, cakey,
     100             :                                        GNUTLS_DIG_SHA256, 0));
     101             : 
     102          33 :         DEBUG(3,("Generating TLS certificate\n"));
     103          33 :         TLSCHECK(gnutls_x509_crt_init(&crt));
     104          33 :         TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt, 
     105             :                                       GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
     106             :                                       ORGANISATION_NAME, strlen(ORGANISATION_NAME)));
     107          33 :         TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt, 
     108             :                                       GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0,
     109             :                                       UNIT_NAME, strlen(UNIT_NAME)));
     110          33 :         TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt,
     111             :                                       GNUTLS_OID_X520_COMMON_NAME, 0,
     112             :                                       hostname, strlen(hostname)));
     113          33 :         TLSCHECK(gnutls_x509_crt_set_key(crt, key));
     114          33 :         TLSCHECK(gnutls_x509_crt_set_serial(crt, &serial, sizeof(serial)));
     115          33 :         TLSCHECK(gnutls_x509_crt_set_activation_time(crt, activation));
     116          33 :         TLSCHECK(gnutls_x509_crt_set_expiration_time(crt, expiry));
     117          33 :         TLSCHECK(gnutls_x509_crt_set_ca_status(crt, 0));
     118          33 :         TLSCHECK(gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0));
     119          33 :         TLSCHECK(gnutls_x509_crt_set_version(crt, 3));
     120          33 :         TLSCHECK(gnutls_x509_crt_get_key_id(crt, 0, keyid, &keyidsize));
     121          33 :         TLSCHECK(gnutls_x509_crt_set_subject_key_id(crt, keyid, keyidsize));
     122          33 :         TLSCHECK(gnutls_x509_crt_sign2(crt, crt, key,
     123             :                                        GNUTLS_DIG_SHA256, 0));
     124          33 :         TLSCHECK(gnutls_x509_crt_sign2(crt, cacrt, cakey,
     125             :                                        GNUTLS_DIG_SHA256, 0));
     126             : 
     127          33 :         DEBUG(3,("Exporting TLS keys\n"));
     128             : 
     129          33 :         bufsize = sizeof(buf);
     130          33 :         TLSCHECK(gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, buf, &bufsize));
     131          33 :         if (!file_save(certfile, buf, bufsize)) {
     132           0 :                 DEBUG(0,("Unable to save certificate in %s parent dir exists ?\n", certfile));
     133           0 :                 goto failed;
     134             :         }
     135             : 
     136          33 :         bufsize = sizeof(buf);
     137          33 :         TLSCHECK(gnutls_x509_crt_export(cacrt, GNUTLS_X509_FMT_PEM, buf, &bufsize));
     138          33 :         if (!file_save(cafile, buf, bufsize)) {
     139           0 :                 DEBUG(0,("Unable to save ca cert in %s parent dir exists ?\n", cafile));
     140           0 :                 goto failed;
     141             :         }
     142             : 
     143          33 :         bufsize = sizeof(buf);
     144          33 :         TLSCHECK(gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buf, &bufsize));
     145          33 :         if (!file_save_mode(keyfile, buf, bufsize, 0600)) {
     146           0 :                 DEBUG(0,("Unable to save privatekey in %s parent dir exists ?\n", keyfile));
     147           0 :                 goto failed;
     148             :         }
     149             : 
     150          33 :         gnutls_x509_privkey_deinit(key);
     151          33 :         gnutls_x509_privkey_deinit(cakey);
     152          33 :         gnutls_x509_crt_deinit(cacrt);
     153          33 :         gnutls_x509_crt_deinit(crt);
     154             : 
     155          33 :         DEBUG(0,("TLS self-signed keys generated OK\n"));
     156          33 :         return;
     157             : 
     158           0 : failed:
     159           0 :         DEBUG(0,("TLS certificate generation failed\n"));
     160             : }

Generated by: LCOV version 1.14