Creating openssl.conf for Windows
Tags: openssl, windows, certificate, linux
Published: 2021-11-02 05:14:07

In this chapter, I will explain how to create **openssl.conf** file with the way that Windows can process it.

---

## Parts to be changed in the default openssl.conf:

For creating a default [openssl.conf](https://jamielinux.com/docs/openssl-certificate-authority/appendix/root-configuration-file.html), Jamie's amazing [article](https://jamielinux.com/docs/openssl-certificate-authority/) would be a good start point.

There are many differences between original Windows certificates and those created with using OpenSSL on Linux:

<p>&nbsp;</p>

### Difference 1 → Issuer:
Issuer is one of the most important field in the certificates. This must be interpreted correctly in order to make Windows accept our handcrafted certificate. 

Difference between certificate created with default openssl.conf and original Windows certificate:

![diff](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fvdm0htr8fjf39xt1ydu.png)

<p>&nbsp;</p>

### Solution for Difference 1:
In this part, we define the section for the **req** command. 

We can edit default_bits, default_md parts. But most importantly, we can change how to form the **DN** with editing the **req_distinguished_name** section.

Default **[ req ]** part would be similar to:
```
[ req ]

default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = utf8only
default_md = sha256
x509_extensions = v3_ca
```
Corresponding default [ req_distinguished_name ] :
```bash
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name
emailAddress                    = Email Address
```
As you can see, there are lots of fields like countryName, stateOrProvinceName, localityName...

This is why we see lots of information in the 'Issuer' field of the certificates created with OpenSSL. 

Edited **[ req_distinguished_name ]** should be similar to:

```bash
[ req_distinguished_name ]

1.DC = com
0.DC = company
DC = subdomain
commonName = Common Name
```

And user should type in that order:
![order](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0lhyee9os78ht3c8nkon.png)

As a result, we successfully created a valid issuer:
![result1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g8sqrtvmudgi617pp2cu.png)

<p>&nbsp;</p>

### Difference 2 → Missing Fields:

Two fields, "Certificate Template Name" and "CA Version", are not available on the certificate that created with OpenSSL on Linux.

It is hard to know about which fields are precisely checked when tricking Windows to accept your handcrafted OpenSSL certificate, but I think it is a good practice to make your certificate look exactly like the original one.

![missingfields](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aq7b29a6dx2wdz2kzmyt.png)

<p>&nbsp;</p>

### Solution for Difference 2:

Firstly, define OID's at the top of our openssl.conf file:

```scheme
oid_section = OIDs

[ OIDs ]

certificateTemplateName = 1.3.6.1.4.1.311.20.2
caVersion = 1.3.6.1.4.1.311.21.1
```

> We can skip the definition of the OID's and use the OID directly, of course. But defining them first and using them as variables would be a good practice.
> 

Secondly, create a new requirement in **[ reg ],** let's say **v3_req** :

```scheme
[ req ]

default_bits = 2048
distinguished_name = req_distinguished_name
string_mask = default
default_md = sha256
x509_extensions = v3_ca
req_extensions = v3_req
```

Lastly, define **[ v3_req ]** :

```scheme
[ v3_req ]

subjectKeyIdentifier = hash
basicConstraints = critical, CA:true
keyUsage = digitalSignature, cRLSign, keyCertSign
certificateTemplateName = ASN1:PRINTABLESTRING:CA
caVersion = ASN1:INTEGER:0
```

After that, you should create your certificate with the following parameter:

```bash
-extensions v3_req
```

As a result, we successfully created our certificate fields:
![result2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/87i44tvxoysjt6cgyp7p.png)

<p>&nbsp;</p>

## Final:
We have successfully created our openssl.conf!
You can view the whole openssl.conf file from: [GitHub Gist](https://gist.github.com/oz9un/60cb7d491989002578d7d763dfda333c)

![final](https://media4.giphy.com/media/nCRkXBaeCPyeX1fkrc/giphy.gif?cid=ecf05e47k54y73o40fa5zl14tw2o0pgpq90lalfatqndx668&rid=giphy.gif&ct=g)