Giter Site home page Giter Site logo

crossroot_lab's Introduction

How to create Cross Root Certificate with CRL endpoint

flowchart TB
    subgraph four-tiers
    Root_CA_1-->ROOT_CA_2'
    ROOT_CA_2'-->INTERMEDIATE_CA
    subgraph three-tiers
    INTERMEDIATE_CA-->SERVER_CERT
    ROOT_CA_2-->INTERMEDIATE_CA
    end
    end
    ROOT_CA_2-. Same Private Key .-ROOT_CA_2'

Requirements

  • openssl 3.0.x
  • PowerShell 5.x or 7.x
  • Web server that stores the CRL (I use Azure Blob with Force Encryption set to False)

Helper function

switch ($PSEdition) {
    "Desktop" { 
        Function Out-FileWithUTF8 {
            param(
                [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
                [string]$Content,
                [Parameter(Mandatory=$true)]
                [string]$Path
            )
            $Content | %{[Text.Encoding]::UTF8.GetBytes($_)} | Set-Content -Encoding Byte -Path $Path
        }
     }
    "Core" {
        Function Out-FileWithUTF8 {
            param(
                [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
                [string]$Content,
                [Parameter(Mandatory=$true)]
                [string]$Path
            )
            $Content | Out-File -Encoding utf8 -FilePath $Path -NoNewline
        }
    }
}

Create Folders

$configPath = Join-Path -Path $(Get-Location) -ChildPath openssl.cnf
$env:OPENSSL_CONF = $configPath

$ENV:ALT_NAME = "altname.example.com"
$CRL_FOR_ROOT_CA_1 = "http://your-host/root_ca_1.crl"
$CRL_FOR_ROOT_CA_2 = "http://your-host/root_ca_2.crl"
$CaList = "root_ca_1","root_ca_2","intermediate_ca"
$CaList | %{ New-Item -Type Directory "$_\ca" }
$CaList | %{
    cd "$_\ca"
    New-Item -Type Directory "certs", "crl","newcerts","private"
    "0001" | Out-String | Out-FileWithUTF8 -Path serial
    New-Item -Type File -Path index.txt
    "0001" | Out-String | Out-FileWithUTF8 -Path crlnumber
    cd ../../
}

Create Root CAs

openssl genrsa -out ./root_ca_1/ca/private/ca.key.pem 2048
openssl req -reqexts v3_req -new -key ./root_ca_1/ca/private/ca.key.pem -x509 -nodes -days 3650 -out ./root_ca_1/ca/certs/ca.crt.pem -subj "/C=JP/ST=Tokyo/L=Shinagawa/O=Contoso/OU=CA/CN=ROOT_CA_1"

openssl genrsa -out ./root_ca_2/ca/private/ca.key.pem 2048
openssl req -reqexts v3_req -new -key ./root_ca_2/ca/private/ca.key.pem -x509 -nodes -days 3650 -out ./root_ca_2/ca/certs/self.ca.crt.pem -subj "/C=JP/ST=Tokyo/L=Shinagawa/O=Contoso/OU=CA/CN=ROOT_CA_2"

Sign ROOT_CA_2 with ROOT_CA_1 (Cross root)

openssl req -new -key ./root_ca_2/ca/private/ca.key.pem -out ./root_ca_2/ca/certs/cert.req -subj "/C=JP/ST=Tokyo/L=Shinagawa/O=Contoso/OU=CA/CN=ROOT_CA_2"

Signed with ROOT_CA_1

$env:CRL_URL=$CRL_FOR_ROOT_CA_1
cd root_ca_1
openssl ca  -extensions v3_ca_with_crl -in ../root_ca_2/ca/certs/cert.req -days 3650 -out ../root_ca_2/ca/certs/ca.crt.pem
cd ..
[ v3_ca_with_crl ]

# Extensions to add to a certificate request

basicConstraints = CA:TRUE
keyUsage = critical, cRLSign, keyCertSign

crlDistributionPoints = URI:$ENV::CRL_URL

# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer

Then ROOT_CA_1 ca behave as Intermediate CA.

Create Intermediate CA

openssl genrsa -out ./intermediate_ca/ca/private/ca.key.pem 2048
openssl req -new -key ./intermediate_ca/ca/private/ca.key.pem -out ./intermediate_ca/ca/certs/cert.req -subj "/C=JP/ST=Tokyo/L=Shinagawa/O=Contoso/OU=CA/CN=INTERMEDIATE_CA"

Signed with ROOT_CA_2

$env:CRL_URL=$CRL_FOR_ROOT_CA_2
cd root_ca_2
openssl ca -extensions v3_ca_with_crl -in ../intermediate_ca/ca/certs/cert.req -days 3650 -out ../intermediate_ca/ca/certs/ca.crt.pem
cd ../

Create Server Certificate

[ v3_server_req ]
basicConstraints=CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

subjectAltName = @alt_names

# CRL is not needed in my environment
# crlDistributionPoints = URI:$ENV::CRL_URL

[ alt_names ]
DNS.1 = $ENV::ALT_NAME
cd intermediate_ca
openssl genrsa -out ./server.key 2048
openssl req  -new -extensions v3_server_req -key ./server.key -out server.csr -subj "/C=JP/ST=Tokyo/L=Shinagawa/O=Contoso/OU=CA/CN=$($env:ALT_NAME)"
openssl ca -extensions  v3_server_req -in ./server.csr -days 365 -out ./server.cer
cd ..

Create PFX

New-Item -Type Directory "output"

$ServerCert = Get-Content .\intermediate_ca\server.cer
$IntermediateCert = Get-Content .\intermediate_ca\ca\certs\ca.crt.pem
$RootCA2CertSignedByRootCA1 = Get-Content .\root_ca_2\ca\certs\ca.crt.pem
$RootCA1Cert = Get-Content .\root_ca_1\ca\certs\ca.crt.pem
$CertChain = $ServerCert + $IntermediateCert + $RootCA2CertSignedByRootCA1 + $RootCA1Cert
$CertChain | Out-String | Out-FileWithUTF8 -Path ./output/certchain.cer

$RootCA1Cert | Out-String | Out-FileWithUTF8 -Path./output/ROOT_CA_1.cer
$RootCA2Cert = Get-Content .\root_ca_2\ca\certs\self.ca.crt.pem
$RootCA2Cert | Out-String | Out-FileWithUTF8 -Path ./output/ROOT_CA_2.cer
$RootCA2CertSignedByRootCA1 | Out-String | Out-FileWithUTF8 -Path ./output/ROOT_CA_2_singed_by_CA1.cer

openssl pkcs12 -export -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES -nomac -out ./server.pfx  -inkey ./intermediate_ca/server.key -in ./certchain.cer -nodes

Certificates and pxf are saved in output folder.

  • ROOT_CA_1.cer: self-signed root ca 1 certificate
  • ROOT_CA_2.cer: self-signed root ca 2 certificate
  • ROOT_CA_2_singed_by_CA1.cer: root ca 2 certificate signed by ca 1
  • certchaing.cer: Full chain certificates (ROOT_CA_1 -> ROOT_CA_2 -> INTERMEDIATE_CA -> SERVER_CERT)
  • server.pfx: Server certificate include private key and full chain certificates

Revoke Intermediate Certificate

# revoke root ca 2
cd root_ca_1
openssl ca -revoke .\ca\newcerts\01.pem
openssl ca  -gencrl -crldays 1 -out ../output/crossrootlab_root_ca_1.crl
cd ..

cd root_ca_2
openssl ca -gencrl -crldays 1 -out ../output/crossrootlab_root_ca_2.crl
cd ..

upload crls

# example using Azure Blob
azcopy copy ./output/crossrootlab_root_ca_1.crl ""

crossroot_lab's People

Contributors

watahani avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.