LCOV - code coverage report
Current view: top level - source4/lib/tls - tlscert.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 60 75 80.0 %
Date: 2024-02-28 12:06:22 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/tls/tls.h"
      24             : 
      25             : #include <gnutls/gnutls.h>
      26             : #include <gnutls/x509.h>
      27             : 
      28             : #define ORGANISATION_NAME "Samba Administration"
      29             : #define CA_NAME           "Samba - temporary autogenerated CA certificate"
      30             : #define UNIT_NAME         "Samba - temporary autogenerated HOST certificate"
      31             : #define LIFETIME          700*24*60*60
      32             : 
      33             : /* FIPS140-2 only allows 2048 or 3072 prime sizes. */
      34             : #define RSA_BITS gnutls_fips140_mode_enabled() ? 3072 : 4096
      35             : 
      36             : /* 
      37             :    auto-generate a set of self signed certificates
      38             : */
      39          33 : void tls_cert_generate(TALLOC_CTX *mem_ctx, 
      40             :                        const char *hostname, 
      41             :                        const char *keyfile, const char *certfile,
      42             :                        const char *cafile)
      43             : {
      44           0 :         gnutls_x509_crt_t cacrt, crt;
      45           0 :         gnutls_x509_privkey_t key, cakey;
      46          33 :         uint32_t serial = (uint32_t)time(NULL);
      47           0 :         unsigned char keyid[100];
      48           0 :         char buf[4096];
      49           0 :         size_t bufsize;
      50          33 :         size_t keyidsize = sizeof(keyid);
      51          33 :         time_t activation = time(NULL), expiry = activation + LIFETIME;
      52           0 :         int ret;
      53             : 
      54          33 :         if (file_exist(keyfile) || file_exist(certfile) || file_exist(cafile)) {
      55           0 :                 DEBUG(0,("TLS autogeneration skipped - some TLS files already exist\n"));
      56          33 :                 return;
      57             :         }
      58             : 
      59             : #define TLSCHECK(call) do { \
      60             :         ret = call; \
      61             :         if (ret < 0) { \
      62             :                 DEBUG(0,("TLS %s - %s\n", #call, gnutls_strerror(ret))); \
      63             :                 goto failed; \
      64             :         } \
      65             : } while (0)
      66             : 
      67          33 :         DEBUG(0,("Attempting to autogenerate TLS self-signed keys for https for hostname '%s'\n", 
      68             :                  hostname));
      69             : 
      70          33 :         DEBUG(3,("Generating private key\n"));
      71          33 :         TLSCHECK(gnutls_x509_privkey_init(&key));
      72          33 :         TLSCHECK(gnutls_x509_privkey_generate(key,   GNUTLS_PK_RSA, RSA_BITS, 0));
      73             : 
      74          33 :         DEBUG(3,("Generating CA private key\n"));
      75          33 :         TLSCHECK(gnutls_x509_privkey_init(&cakey));
      76          33 :         TLSCHECK(gnutls_x509_privkey_generate(cakey, GNUTLS_PK_RSA, RSA_BITS, 0));
      77             : 
      78          33 :         DEBUG(3,("Generating CA certificate\n"));
      79          33 :         TLSCHECK(gnutls_x509_crt_init(&cacrt));
      80          33 :         TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, 
      81             :                                       GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
      82             :                                       ORGANISATION_NAME, strlen(ORGANISATION_NAME)));
      83          33 :         TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, 
      84             :                                       GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0,
      85             :                                       CA_NAME, strlen(CA_NAME)));
      86          33 :         TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt,
      87             :                                       GNUTLS_OID_X520_COMMON_NAME, 0,
      88             :                                       hostname, strlen(hostname)));
      89          33 :         TLSCHECK(gnutls_x509_crt_set_key(cacrt, cakey));
      90          33 :         TLSCHECK(gnutls_x509_crt_set_serial(cacrt, &serial, sizeof(serial)));
      91          33 :         TLSCHECK(gnutls_x509_crt_set_activation_time(cacrt, activation));
      92          33 :         TLSCHECK(gnutls_x509_crt_set_expiration_time(cacrt, expiry));
      93          33 :         TLSCHECK(gnutls_x509_crt_set_ca_status(cacrt, 1));
      94          33 :         TLSCHECK(gnutls_x509_crt_set_key_usage(cacrt, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN));
      95          33 :         TLSCHECK(gnutls_x509_crt_set_version(cacrt, 3));
      96          33 :         TLSCHECK(gnutls_x509_crt_get_key_id(cacrt, 0, keyid, &keyidsize));
      97          33 :         TLSCHECK(gnutls_x509_crt_set_subject_key_id(cacrt, keyid, keyidsize));
      98          33 :         TLSCHECK(gnutls_x509_crt_sign2(cacrt, cacrt, cakey,
      99             :                                        GNUTLS_DIG_SHA256, 0));
     100             : 
     101          33 :         DEBUG(3,("Generating TLS certificate\n"));
     102          33 :         TLSCHECK(gnutls_x509_crt_init(&crt));
     103          33 :         TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt, 
     104             :                                       GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
     105             :                                       ORGANISATION_NAME, strlen(ORGANISATION_NAME)));
     106          33 :         TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt, 
     107             :                                       GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0,
     108             :                                       UNIT_NAME, strlen(UNIT_NAME)));
     109          33 :         TLSCHECK(gnutls_x509_crt_set_dn_by_oid(crt,
     110             :                                       GNUTLS_OID_X520_COMMON_NAME, 0,
     111             :                                       hostname, strlen(hostname)));
     112          33 :         TLSCHECK(gnutls_x509_crt_set_key(crt, key));
     113          33 :         TLSCHECK(gnutls_x509_crt_set_serial(crt, &serial, sizeof(serial)));
     114          33 :         TLSCHECK(gnutls_x509_crt_set_activation_time(crt, activation));
     115          33 :         TLSCHECK(gnutls_x509_crt_set_expiration_time(crt, expiry));
     116          33 :         TLSCHECK(gnutls_x509_crt_set_ca_status(crt, 0));
     117          33 :         TLSCHECK(gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0));
     118          33 :         TLSCHECK(gnutls_x509_crt_set_version(crt, 3));
     119          33 :         TLSCHECK(gnutls_x509_crt_get_key_id(crt, 0, keyid, &keyidsize));
     120          33 :         TLSCHECK(gnutls_x509_crt_set_subject_key_id(crt, keyid, keyidsize));
     121          33 :         TLSCHECK(gnutls_x509_crt_sign2(crt, crt, key,
     122             :                                        GNUTLS_DIG_SHA256, 0));
     123          33 :         TLSCHECK(gnutls_x509_crt_sign2(crt, cacrt, cakey,
     124             :                                        GNUTLS_DIG_SHA256, 0));
     125             : 
     126          33 :         DEBUG(3,("Exporting TLS keys\n"));
     127             : 
     128          33 :         bufsize = sizeof(buf);
     129          33 :         TLSCHECK(gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, buf, &bufsize));
     130          33 :         if (!file_save(certfile, buf, bufsize)) {
     131           0 :                 DEBUG(0,("Unable to save certificate in %s parent dir exists ?\n", certfile));
     132           0 :                 goto failed;
     133             :         }
     134             : 
     135          33 :         bufsize = sizeof(buf);
     136          33 :         TLSCHECK(gnutls_x509_crt_export(cacrt, GNUTLS_X509_FMT_PEM, buf, &bufsize));
     137          33 :         if (!file_save(cafile, buf, bufsize)) {
     138           0 :                 DEBUG(0,("Unable to save ca cert in %s parent dir exists ?\n", cafile));
     139           0 :                 goto failed;
     140             :         }
     141             : 
     142          33 :         bufsize = sizeof(buf);
     143          33 :         TLSCHECK(gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buf, &bufsize));
     144          33 :         if (!file_save_mode(keyfile, buf, bufsize, 0600)) {
     145           0 :                 DEBUG(0,("Unable to save privatekey in %s parent dir exists ?\n", keyfile));
     146           0 :                 goto failed;
     147             :         }
     148             : 
     149          33 :         gnutls_x509_privkey_deinit(key);
     150          33 :         gnutls_x509_privkey_deinit(cakey);
     151          33 :         gnutls_x509_crt_deinit(cacrt);
     152          33 :         gnutls_x509_crt_deinit(crt);
     153             : 
     154          33 :         DEBUG(0,("TLS self-signed keys generated OK\n"));
     155          33 :         return;
     156             : 
     157           0 : failed:
     158           0 :         DEBUG(0,("TLS certificate generation failed\n"));
     159             : }

Generated by: LCOV version 1.14