Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    Trying to create OpenVPN user certs manually

    Scheduled Pinned Locked Moved OpenVPN
    3 Posts 1 Posters 1.2k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • K
      keylevel
      last edited by

      I need to be able to create a (large) set of user certs for OpenVPN, so I want to be able to run a local script to do this. The basic code I'm using is:

      
      $CA_CERT = "VPN-CA.crt";
      $CA_KEY  = "VPN-CA.key";
      
      $digest_alg = "sha512";
      $keylen = 4096;
      
      $args = array (
        "x509_extensions" => "usr_cert",
        "digest_alg" => $digest_alg,
        "private_key_bits" => (int)$keylen,
        "private_key_type" => OPENSSL_KEYTYPE_RSA,
        "encrypt_key" => false );
      
      $req_key = openssl_pkey_new( $args );
      
      if( openssl_pkey_export ( $req_key, $out_key ) ) {
        $dn = array(
          "countryName" => "GB",
          "stateOrProvinceName" => "...",
          "localityName" => "...",
          "organizationName" => "...",
          "emailAddress" => "...",
          "commonName" => "..."
        );
      
        $req_csr  = openssl_csr_new  ( $dn, $req_key, $args );
        $req_cert = openssl_csr_sign ( $req_csr, "file://$CA_CERT", "file://$CA_KEY", 365, $args );
      
        if( openssl_x509_export ( $req_cert, $out_cert ) ) {
          $umask = umask(0066);
      
          if ( ! openssl_pkcs12_export_to_file( $req_cert, "user.p12", $req_key, "" ) )
          {
            echo "Failed p12\n";
          }
      }
      
      

      Where "VPN-CA" is a self-signed CA generated using the pfSense Cert Manager. This is also used to create a server certificate for use by the OpenVPN server.

      I'm then using the .p12 this produces to replace the one in a client export produced using the OpenVPN Client Export package.

      The exported package (unmodified) works as expected and I can connect and create a tunnel.

      However, when I use the .p12 generated using my script I am seeing the following in the logs (Tunnelblick):

      2016-08-09 10:10:39 TLS: Initial packet from [AF_INET]xx.xx.xx.xxx:1194, sid=54773c0c d9fca608
      2016-08-09 10:10:39 VERIFY ERROR: depth=1, error=self signed certificate in certificate chain: C=..., ST=..., L=..., O=..., emailAddress=..., CN=...
      2016-08-09 10:10:39 OpenSSL: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed
      2016-08-09 10:10:39 TLS_ERROR: BIO read tls_read_plaintext error
      2016-08-09 10:10:39 TLS Error: TLS object -> incoming plaintext read error
      2016-08-09 10:10:39 TLS Error: TLS handshake failed
      
      

      I think my code has the same behaviour as the code pfSense uses to create the user cert (system_certmanager.php), but I must be missing something. Can anyone see what I'm doing wrong?

      Chris

      1 Reply Last reply Reply Quote 0
      • K
        keylevel
        last edited by

        Should add that running:

        openssl verify -verbose -CAfile VPN-CA.crt user.crt
        

        where 'user.cdt' was extracted from 'user.p12' reports that the user cert is valid.

        Chris

        1 Reply Last reply Reply Quote 0
        • K
          keylevel
          last edited by

          Ok, this:

          if ( ! openssl_pkcs12_export_to_file( $req_cert, "user.p12", $req_key, "" ) )
          

          is the problem. The .p12 produced only contains the user cert - I need to add the CA cert as well.

          However, it doesn't look like there's a php openssl_ function to do this - which is probably why the openVPN Client Export Plugin uses:

          exec("/usr/bin/openssl pkcs12 -export -in {$ecrtpath} -inkey {$ekeypath} -certfile {$ecapath} -out {$eoutpath} -passout pass:{$eoutpass}");
          

          Chris

          1 Reply Last reply Reply Quote 0
          • First post
            Last post
          Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.