PHP 7.0.6 Released

openssl_csr_new

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

openssl_csr_newGenerates a CSR

Description

mixed openssl_csr_new ( array $dn , resource &$privkey [, array $configargs [, array $extraattribs ]] )

openssl_csr_new() generates a new CSR (Certificate Signing Request) based on the information provided by dn, which represents the Distinguished Name to be used in the certificate.

Note: You need to have a valid openssl.cnf installed for this function to operate correctly. See the notes under the installation section for more information.

Parameters

dn

The Distinguished Name to be used in the certificate.

privkey

privkey should be set to a private key that was previously generated by openssl_pkey_new() (or otherwise obtained from the other openssl_pkey family of functions). The corresponding public portion of the key will be used to sign the CSR.

configargs

By default, the information in your system openssl.conf is used to initialize the request; you can specify a configuration file section by setting the config_section_section key of configargs. You can also specify an alternative openssl configuration file by setting the value of the config key to the path of the file you want to use. The following keys, if present in configargs behave as their equivalents in the openssl.conf, as listed in the table below.

Configuration overrides
configargs key type openssl.conf equivalent description
digest_alg string default_md Selects which digest method to use
x509_extensions string x509_extensions Selects which extensions should be used when creating an x509 certificate
req_extensions string req_extensions Selects which extensions should be used when creating a CSR
private_key_bits integer default_bits Specifies how many bits should be used to generate a private key
private_key_type integer none Specifies the type of private key to create. This can be one of OPENSSL_KEYTYPE_DSA, OPENSSL_KEYTYPE_DH or OPENSSL_KEYTYPE_RSA. The default value is OPENSSL_KEYTYPE_RSA which is currently the only supported key type.
encrypt_key boolean encrypt_key Should an exported key (with passphrase) be encrypted?
encrypt_key_cipher integer none One of cipher constants.

extraattribs

extraattribs is used to specify additional configuration options for the CSR. Both dn and extraattribs are associative arrays whose keys are converted to OIDs and applied to the relevant part of the request.

Return Values

Returns the CSR.

Examples

Example #1 Creating a self-signed-certificate

<?php
// Fill in data for the distinguished name to be used in the cert
// You must change the values of these keys to match your name and
// company, or more precisely, the name and company of the person/site
// that you are generating the certificate for.
// For SSL certificates, the commonName is usually the domain name of
// that will be using the certificate, but for S/MIME certificates,
// the commonName will be the name of the individual who will use the
// certificate.
$dn = array(
    
"countryName" => "UK",
    
"stateOrProvinceName" => "Somerset",
    
"localityName" => "Glastonbury",
    
"organizationName" => "The Brain Room Limited",
    
"organizationalUnitName" => "PHP Documentation Team",
    
"commonName" => "Wez Furlong",
    
"emailAddress" => "wez@example.com"
);

// Generate a new private (and public) key pair
$privkey openssl_pkey_new();

// Generate a certificate signing request
$csr openssl_csr_new($dn$privkey);

// You will usually want to create a self-signed certificate at this
// point until your CA fulfills your request.
// This creates a self-signed cert that is valid for 365 days
$sscert openssl_csr_sign($csrnull$privkey365);

// Now you will want to preserve your private key, CSR and self-signed
// cert so that they can be installed into your web server, mail server
// or mail client (depending on the intended use of the certificate).
// This example shows how to get those things into variables, but you
// can also store them directly into files.
// Typically, you will send the CSR on to your CA who will then issue
// you with the "real" certificate.
openssl_csr_export($csr$csrout) and var_dump($csrout);
openssl_x509_export($sscert$certout) and var_dump($certout);
openssl_pkey_export($privkey$pkeyout"mypassword") and var_dump($pkeyout);

// Show any errors that occurred here
while (($e openssl_error_string()) !== false) {
    echo 
$e "\n";
}
?>

User Contributed Notes

The_Lost_One
6 years ago
Not sure whether the "bug" (undocumented behavior) I encountered is common to other people, but this comment might save hours of painful debug:
If you can't generate a new private key using openssl_pkey_new() or openssl_csr_new(), your script hangs during the call of these functions and in case you specified a "private_key_bits" parameter, ensure that you cast the variable to an int. Took me ages to notice that.

<?php
$SSLcnf
= array('config' => '/usr/local/nessy2/share/ssl/openssl.cnf',
       
'encrypt_key' => true,
       
'private_key_type' => OPENSSL_KEYTYPE_RSA,
       
'digest_alg' => 'sha1',
       
'x509_extensions' => 'v3_ca',
       
'private_key_bits' => $someVariable // ---> bad
       
'private_key_bits' => (int)$someVariable // ---> good
       
'private_key_bits' => 512 // ---> obviously good
       
);
?>
alex at nodex dot co dot uk
1 year ago
In the PHP example above it uses "UK" as the country name which is incorrect, the country name must be "GB"
james at kirk dot com
10 months ago
When in doubt, read the source code to PHP!

$configargs is fairly opaque as to what is going on behind the scenes.  That is, until you actually look at php_openssl_parse_config() in '/ext/openssl/openssl.c':

    SET_OPTIONAL_STRING_ARG("digest_alg", req->digest_name,
        CONF_get_string(req->req_config, req->section_name, "default_md"));
    SET_OPTIONAL_STRING_ARG("x509_extensions", req->extensions_section,
        CONF_get_string(req->req_config, req->section_name, "x509_extensions"));
    SET_OPTIONAL_STRING_ARG("req_extensions", req->request_extensions_section,
        CONF_get_string(req->req_config, req->section_name, "req_extensions"));
    SET_OPTIONAL_LONG_ARG("private_key_bits", req->priv_key_bits,
        CONF_get_number(req->req_config, req->section_name, "default_bits"));

    SET_OPTIONAL_LONG_ARG("private_key_type", req->priv_key_type, OPENSSL_KEYTYPE_DEFAULT);

Here we can see that SET_OPTIONAL_STRING_ARG() is called for most inputs but for 'private_key_bits' SET_OPTIONAL_LONG_ARG() is called.  Both calls are C macros that expand to code that enforces the expected input type.  The generated code ignores the input without warning/notice if an unexpected type is used and just uses the default from the configuration file.  This is why using a string with 'private_key_bits' will result in unexpected behavior.

Further inspection of the earlier initialization in the same function:

    SET_OPTIONAL_STRING_ARG("config", req->config_filename, default_ssl_conf_filename);
    SET_OPTIONAL_STRING_ARG("config_section_name", req->section_name, "req");
    req->global_config = CONF_load(NULL, default_ssl_conf_filename, NULL);
    req->req_config = CONF_load(NULL, req->config_filename, NULL);

    if (req->req_config == NULL) {
        return FAILURE;
    }

And elsewhere in another function:

    /* default to 'openssl.cnf' if no environment variable is set */
    if (config_filename == NULL) {
        snprintf(default_ssl_conf_filename, sizeof(default_ssl_conf_filename), "%s/%s",
                X509_get_default_cert_area(),
                "openssl.cnf");
    } else {
        strlcpy(default_ssl_conf_filename, config_filename, sizeof(default_ssl_conf_filename));
    }

Reveals that 'config' in $configargs is an override for any default setting elsewhere.  This actually negates the comment in the documentation that says "Note: You need to have a valid openssl.cnf installed for this function to operate correctly. See the notes under the installation section for more information."  A more correct sentence would be "Note:  You need to either have a valid openssl.cnf set up or use $configargs to point at a valid openssl.cnf file for this function to operate correctly."

All of that goes to show that looking at the PHP source code is the only real way to figure out what is actually happening.  Doing so saves time and effort.
Anonymous
1 year ago
For those of you using Debian-based systems, the openssl configuration file is at: /etc/ssl/openssl.cnf
Richard Lynch
2 years ago
There appears to be no openssl_csr_free function.

At least not here.

If it's in the source, one might be able to just call it.

If it's not in the source, it probably should be.
main ATT jokester DOTT fr
7 years ago
To set the "basicConstraints" to  "critical,CA:TRUE", you have to define configargs, but in the openssl_csr_sign() function !

That's my example of code to sign a "child" certificate :

$CAcrt = "file://ca.crt";
$CAkey = array("file://ca.key", "myPassWord");

$clientKeys = openssl_pkey_new();
$dn = array(
    "countryName" => "FR",
    "stateOrProvinceName" => "Finistere",
    "localityName" => "Plouzane",
    "organizationName" => "Ecole Nationale d'Ingenieurs de Brest",
    "organizationalUnitName" => "Enib Students",
    "commonName" => "www.enib.fr",
    "emailAddress" => "ilovessl@php.net"
);
$csr = openssl_csr_new($dn, $clientPrivKey);

$configArgs = array("x509_extensions" => "v3_req");
$cert = openssl_csr_sign($csr, $CAcrt, $CAkey, 100, $configArgs);

openssl_x509_export_to_file($cert, "childCert.crt");

Then if you want to add some more options, you can edit the "/etc/ssl/openssl.cnf" ssl config' file (debian path), and add these after the [ v3_req ] tag.
Anonymous
10 years ago
If you get the error:

error:0D11A086:asn1 encoding routines:ASN1_mbstring_copy:string too short

then look at your key:value pairs in the $dn (distinguished name) array.

If you have one value (like "organizationalUnitName" = "") set to an empty string, it will throw the above error.

Fix the error by either eliminating that array element from $dn completely, or using a space " " instead of an empty string.
robertliu AT wiscore DOT com
10 years ago
I am using PHP-4.3.11.
The type of configargs--private_key_bits is a INTEGER, not a string.
An example of configration:
<?php
$config
= array(
 
"digest_alg" => "sha1",
 
"private_key_bits" => 2048,
 
"private_key_type" => OPENSSL_KEYTYPE_DSA,
 
"encrypt_key" => false
);
?>
dankybastard at hotmail
11 years ago
As you probably guessed from the example, the documentation is misinforming.  openssl_csr_new returns a CSR resource or FALSE on failure.

mixed openssl_csr_new (assoc_array dn, resource_privkey, [...])
dylan at pow7 dot com
8 years ago
Is there some way to change the distinguished name using this function? I have tried adding overrides to the dn to configargs and extraattribs but this did not have an impact on the certificate.

Example: A CSR is submitted and I want to change only the commonName (CN) before signing the certificate.
gonzak at op dot pl
10 years ago
How in openssl_csr_new  usign [, array configargs [, array extraattribs]]
because I am have add this extension to certificate
/********************
basicConstraints = critical,CA:TRUE,pathlen:0
nsCertType = sslCA,emailCA,objCA
**********************************/

Rafal
To Top