1

I have this cert_functions.ps1 file

$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'
function New-WorkstationCertificateRequestConfiguration {
    param(
        [Parameter(Mandatory=$true)]
        [string]$DOMAIN,
        [Parameter(Mandatory=$true)]
        [string]$ORGANIZATION
    )

    # static parameters
    $keyAlgorithm = 'RSA'
    $keySize = '2048'
    $hashAlgorithm = 'sha256'

    $template = @'
; Request.inf
[Version]
Signature="`$Windows NT$"

[NewRequest]
Subject = "CN=_DOMAIN_NAME_,C=ES,ST=YYYYYYYYY,L=XXXXXXXX,O=_ORGANIZATION_"
MachineKeySet = TRUE
KeyLength = _KEY_SIZE_
KeySpec=1
Exportable = TRUE
ExportableEncrypted = TRUE
RequestType = PKCS10
HashAlgorithm = _HASH_ALGORITHM_
KeyAlgorithm = _KEY_ALGORITHM_
SMIME = FALSE
EncryptionAlgorithm = AES
EncryptionLength = 128
ProviderName = "Microsoft Software Key Storage Provider"
FriendlyName = _DOMAIN_NAME_

[Extensions]
; If your client operating system is Windows Server 2008, Windows Server 2008 R2, Windows Vista, or Windows 7
; SANs can be included in the Extensions section by using the following text format. Note 2.5.29.17 is the OID for a SAN extension.

2.5.29.17 = "{text}"
_continue_ = "DNS=_DOMAIN_NAME_&"
_continue_ = "DNS=testing._DOMAIN_NAME_&"
'@
   
        $template = $template -replace '_DOMAIN_NAME_',$DOMAIN
        $template = $template -replace '_ORGANIZATION_',$ORGANIZATION
        $template = $template -replace '_KEY_ALGORITHM_',$keyAlgorithm
        $template = $template -replace '_KEY_SIZE_',$keySize
        $template = $template -replace '_HASH_ALGORITHM_',$hashAlgorithm

        return $template
}

function New-WebHostingCertificate {
    param(
        [parameter(mandatory=$true)]
        [string]$domain,
        [string]$organization,
        [string]$authoritycertificatesserver = "localhost\MYORG-AD01-CA"
    )
    
    # check if $organization is not provided as an argument
    if (-not $organization) {
        # derive $organization from $domain (hostname without tld and subdomains)
        $organization = get-organization -domain $domain
    } else {
        echo $organization.gettype()
        $organization = $organization.toupper()[0] + $organization.substring(1)
    }
    
    $answerfile = new-temporaryfile
    $requestfile = new-temporaryfile
    $publiccertfile = new-temporaryfile
    $pfxcertfile = new-temporaryfile
    $privatekeyfile = new-temporaryfile
    $certfile = new-temporaryfile
    
    set-content $answerfile.fullname (new-workstationcertificaterequestconfiguration -domain $domain -organization $organization)
    
    # logging progress: creating certificate request
    write-output "creating certificate request..."
    try {
        echo "certreq -new $($answerfile.fullname) $($requestfile.fullname)"
        invoke-expression -command "certreq -new -f -q $($answerfile.fullname) $($requestfile.fullname)"
    } catch {
        write-error "couldn't create certificate request"
        return
    }
    
    # logging progress: submitting certificate request
    write-output "submitting certificate request..."
    try {
        echo "certreq -submit -config $($authoritycertificatesserver) $($requestfile.fullname) $($publiccertfile.fullname)"
        invoke-expression -command "certreq -submit -config $($authoritycertificatesserver) $($requestfile.fullname) $($publiccertfile.fullname) | select-string 'id. de solicitud: (\d+)' | foreach-object { `$_.matches.groups[1].value }"  -outvariable id_solicitud
        # invoke-expression -command "certreq -submit -config $($authoritycertificatesserver) $($requestfile.fullname) $($publiccertfile.fullname)"
    } catch {
        write-error "couldn't submit certificate request"
        return
    }
    
    # logging progress: resubmitting certificate request
    write-output "resubmitting certificate request..."
    try {
        invoke-expression -command "certutil -resubmit $($id_solicitud)"
    } catch {
        write-error "couldn't resubmit certificate request"
        return
    }
    
    # logging progress: retrieving certificate request
    write-output "retrieving certificate request..."
    try {
        invoke-expression -command "certreq -retrieve -f -q -config $($authoritycertificatesserver) $($id_solicitud) $($publiccertfile.fullname)"
    } catch {
        write-error "couldn't retrieve certificate request"
        return
    }
    
    # logging progress: accepting certificate request
    write-output "accepting certificate request..."
    try {
        echo "certreq -accept -f -q -user -config $($authoritycertificatesserver) $($publiccertfile.fullname)"
        invoke-expression -command "certreq -accept -f -q -user -config $($authoritycertificatesserver) $($publiccertfile.fullname)"
    } catch {
        write-error "couldn't accept certificate request"
        return
    }
    
    # get thumbprint of the newly generated certificate
    $certprint = new-object -typename system.security.cryptography.x509certificates.x509certificate2($publiccertfile)
    $thumbprint = $certprint.thumbprint
    
    # logging progress: exporting signed certificate to pfx file
    write-output "exporting signed certificate to pfx file..."
    try {
        echo "certutil -user -exportPFX -p 'foo' my $($thumbprint) cert.pfx"
        invoke-expression -command "certutil -user -exportPFX -p 'foo' my $($thumbprint) cert.pfx"
        if ($LASTEXITCODE -ne 0) {
            Write-Error "An error occurred: $output"
            return
        }
    } catch [System.Exception] {
        $message = $Error[0].Exception.Message
        Write-Error "Couldn't export PFX certificate request $message"
        return
    }
    
    # logging progress: extracting private key from pfx file
    write-output "extracting private key from pfx file..."
    try {
        echo "openssl pkcs12 -in cert.pfx -nocerts -out $($DOMAIN).key"
        invoke-expression -command "openssl pkcs12 -in cert.pfx -nocerts -out $($DOMAIN).key"
    } catch {
        write-error "couldn't extract private key from pfx"
        return
    }

    # logging progress: extracting certificate from pfx file
    write-output "extracting certificate from pfx file..."
    try {
        echo "openssl pkcs12 -in cert.pfx -clcerts -nokeys -out $($DOMAIN).crt"
        invoke-expression -command "openssl pkcs12 -in cert.pfx -clcerts -nokeys -out $($DOMAIN).crt"
    } catch {
        write-error "couldn't extract certificate from pfx"
        return
    }

    # cleanup temporary files
    write-output "cleaning up temporary files..."
    try {
        remove-item $answerfile.fullname, $requestfile.fullname, $publiccertfile.fullname, $pfxcertfile.fullname -force
        write-output "removed temporary files"
    } catch {
        write-error "failed to remove temporary files"
    }

    # security cleanup
    write-output "cleaning up certificate requests..."
    try {
        get-childitem cert:\localmachine\request\ | remove-item -force
    } catch {
        write-error "failed to cleanup certificate requests"
    }
}

function Renew-WebHostingCertificates {
    param(
        [string]$AuthorityCertificatesServer = "localhost\MYORG-AD01-CA"
    )
    
    $keyFiles = Get-ChildItem -File -Filter "*.key" | Where-Object  { ($_.Name -match ".key$") -and ($_.Name -ne "root.key") }

    foreach ($keyFile in $keyFiles) {
        $DOMAIN = $keyFile.Name -replace '\.key$'
        $ORGANIZATION = Get-Organization -DOMAIN $DOMAIN
        
        Invoke-Expression -OutVariable NUMERO_SERIE -Command "certutil -view -restrict `"CommonName=$($DOMAIN),Disposition=20`" -out `"SerialNumber`" | Select-String 'N.*mero de serie: `"(.+)`"' | ForEach-Object { `$_.Matches.Groups[1].Value }"
        
        if ($NUMERO_SERIE) {
            Invoke-Expression -Command "certutil -revoke $($NUMERO_SERIE) 4"
        }
        
        echo $DOMAIN
        echo $ORGANIZATION
        
        New-WebHostingCertificate -DOMAIN $DOMAIN -ORGANIZATION $ORGANIZATION
    }
}


function Get-Organization {
    param(
        [Parameter(Mandatory=$true)]
        [string]$DOMAIN
    )
    
    $regexExpression = "(?<domainname>(?<ip>^[A-Fa-f\d\.:]+$)|(?<nodots>^[^\.]+$)|(?<fqdomain>(?:(?:[^\.]+\.)?(?<tld>(?:[^\.\s]{2})(?:(?:\.[^\.\s][^\.\s])|(?:[^\.\s]+)))))$)"
    if ($DOMAIN -match $regexExpression) {
        # The text matches the regex pattern
        # You can access matched groups like this:
        $domainname = $matches['domainname']
        $ip = $matches['ip']
        $nodots = $matches['nodots']
        $fqdomain = $matches['fqdomain']

        # Use the matched values as needed
        $ORGANIZATION = $domainname.split('.')[0]
    } else {
        $ORGANIZATION = $DOMAIN
    }
    
    return $ORGANIZATION
}

And whenever I want to run it I execute in an admin powershell

cd C:\Apache24\certificates && Import-Module .\cert_functions.ps1 && New-WebHostingCertificate

I get a cert.pfx with the CA and certificate info but the crt and key files are 0KB

Here's an example output:

PS C:\Users\daviid> cd C:\Apache24\certificates && Import-Module .\cert_functions.ps1 && new-WebHostingCertificate

cmdlet New-WebHostingCertificate at command pipeline position 1
Supply values for the following parameters:
domain: example.com
creating certificate request...
certreq -new C:\Users\daviid\AppData\Local\Temp\1\tmpuw1yqs.tmp C:\Users\daviid\AppData\Local\Temp\1\tmpzgbyas.tmp

CertReq: Solicitud creada
submitting certificate request...
certreq -submit -config localhost\MYORG-AD01-CA C:\Users\daviid\AppData\Local\Temp\1\tmpzgbyas.tmp C:\Users\daviid\AppData\Local\Temp\1\tmpa3y433.tmp
152
resubmitting certificate request...
Certificado emitido.
CertUtil: -resubmit comando completado correctamente.
retrieving certificate request...
Id. de solicitud: 152
Id. de solicitud: "152"
Certificado recuperado (Emitida) Emitida  Reenviado por MYORG\daviid
accepting certificate request...
certreq -accept -f -q -user -config localhost\MYORG-AD01-CA C:\Users\daviid\AppData\Local\Temp\1\tmpa3y433.tmp
Certificado instalado:
  Número de serie: 4900000098a01baad244749bbf000000000098
  Sujeto: CN=example.com, O=example, L=XXXXXXXX, S=YYYYYYYYY, C=ES (Nombre DNS=example.com, Nombre DNS=testing.example.com)
  NotBefore: 22/05/2024 20:57
  NotAfter: 22/05/2025 21:07
  Huella digital: 9d8e76343bcda0e03b274393ed7fdb110fe4fa68

exporting signed certificate to pfx file...
certutil -user -exportPFX -p 'foo' my 9D8E76343BCDA0E03B274393ED7FDB110FE4FA68 cert.pfx
my "Personal"
================ Certificado 37 ================
Número de serie: 4900000098a01baad244749bbf000000000098
Emisor: CN=MYORG-AD01-CA, DC=MYORG, DC=COM
 NotBefore: 22/05/2024 20:57
 NotAfter: 22/05/2025 21:07
Sujeto: CN=example.com, O=example, L=XXXXXXXX, S=YYYYYYYYY, C=ES
Certificado no raíz
Hash de cert(sha1): 9d8e76343bcda0e03b274393ed7fdb110fe4fa68
No hay información sobre el proveedor de claves
No se encuentra el certificado y la clave privada para el descifrado.
CertUtil: -exportPFX comando completado correctamente.
extracting private key from pfx file...
openssl pkcs12 -in cert.pfx -nocerts -out example.com.key
Enter Import Password:

extracting certificate from pfx file...
openssl pkcs12 -in cert.pfx -clcerts -nokeys -out example.com.crt
Enter Import Password:

cleaning up temporary files...
removed temporary files
cleaning up certificate requests...
PS C:\Apache24\certificates>

And here's openssl pkcs12 -info -in .\cert.pfx output (base64 modified)

PS C:\Apache24\certificates> openssl pkcs12 -info -in .\cert.pfx
Enter Import Password:

MAC: sha1, Iteration 2000
MAC length: 20, salt length: 20
PKCS7 Encrypted data: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 2000
Certificate bag
Bag Attributes: <Empty Attributes>
subject=DC = COM, DC = MYORG, CN = MYORG-AD01-CA
issuer=DC = COM, DC = MYORG, CN = MYORG-AD01-CA
-----BEGIN CERTIFICATE-----
MOKAmgXigLAw4oCaA3HCoAMCAQICEGPDvsKwHMKBw5ZP4oCZR2DDilwnw4HDjBU
wCgYJKuKAoEjigKDDtwoBAQoF77+9MFcxEzARBgoJ4oCZJuKAsOKAnMOyLGQBGR
YDQ09NMRwwGgYKCeKAmSbigLDigJzDsixkARkWDE1ZT1JHMSIwIAYDVQQDExlNW
U9SRy1BRDAxLUNBMB4XCjIzMDcwMzA5NDIwNloXCjMzMDcwMzA5NTIwNlowVzET
MBEGCgnigJkm4oCw4oCcw7IsZAEZFgNDT00xHDAaBgoJ4oCZJuKAsOKAnMOyLGQ
BGRYMTVlPUkcxIjAgBgNVBAMTGU1ZT1JHLUFEMDEtQ0Ew4oCaAiIwCgYJKuKAoE
jigKDDtwoBAQEF77+9A+KAmgIP77+9MOKAmgIKAuKAmgIB77+9w4rigqzCrsOl4
oC6e2/Ctg7FoMO7BeKAmXoLNcOlIsOK4oKsah7DlsO5wql3wqbDqVDDmsObE8Ku
w5nDmDFgBnRlYDTigJx2DOKAoAhQxb0BKwXDpX3DtMO+w7jDqDMZwr1h4oC6CeK
AoglLxaFuMMO4wp3DgUwpUnRNW8KBYG/DvQdULE/CrsK5a1fDs8O9ClDFoVLCoA
gi4oCmWl5dw6vDshUKwrTDnQpKwqfDlkI/wroUUHUlCUnCtTkQw69CwrBfB8KiU
FNd4oC5w6ZwwrwFOjfDusOXw7fDlklyV8OdG8O2d8K+dBUJXsWSRWsBdcOiKXXv
v73DtcKzw5LDv8ODwo/DnHUR4oSiw6BBQ8K1w74Zw553wrbCozp1B8OOWltycuK
CrFkCxpJ8ARB6w7LDsRp2w7LDkV5axb7DvkXFuMW4HOKAnmN+XMO9BcOKLijDvs
OD4oCTfnNVw5vCoeKAmsOzw7M64oSiDxNp4oC6w7tKwqtDf8OeS8Kdwqtfw58cw
7nDncK0w4Qfw6TDksK/Q07CkArDiRTDhmMcw7bCtjwab8O9w5ImMGRje8aSw4AX
R8OSw7Dvv71RQsKgwqTigJk0TzbigJpAXMOzCk1oC+KAujjDggzDnjVzw68eJcW
TRnbDlAzDpsKrTH7CvsKhw7zDg8O1E+KCrMKlJsOF4oC5aHwgw4QoH8KnEVt0w4
9Pw6lveT3Cs39Rw5tSwqEWEmw6LRJ8dAzCogk7wrsxw5DDksK44oCgwpB0ZsK5V
B1CfMOZEMO0FVRGw6VQw6N3w4Y7wqYWwrrLhsOsw4XigJRLw77CsFBIw6PigLBR
fMucwqwPw7TigJjDtcKqy4Yfw6E7w5rDrHQOVuKAlMaSBVoEIsO8bcOUw6hUw4v
Cu8K1wqdyxaHCjw7DhFvFoCHDoHx14oCiZinDmyDCocWSQ8O3DMK0GhVZeEFhEc
KmfsW+wrnDgn5JTmxyBSPDkinDhsOxSMaSSFNXxb1kCjTDrcK+wrJzy5w3G8ONw
5rCnSLCsB3CsQIDAe+/vQHCo1EwTzALBgNVHQ8EBAMCAeKAoDAPBgNVHRMBAcO/
BAUwAwEBw78wHQYDVR0OBBYEFD8Hw7YGw59kw4nCvXLigJhbw44f4oCiBl/DtcK
mTMO2MBAGCSsGAQQB4oCaNxUBBAMCAe+/vTAKBgkq4oCgSOKAoMO3CgEBCgXvv7
0D4oCaAgHvv71qw6t3woHDpy7igKLFvcOCw70nwrNIHGDDvcKPw6lbwqkgc183J
A7CtMOywqrDunjCp0/CkMK8KwrigJ3DqFpmbOKAocWTw73CqcOk4oCmHSzFk3wh
xbjDuw/CgcOiwqJfwrFrf2rDrsW94oCw4oChw7LigLATKEh6ZMOTw7/DrsKrJ0h
BR8OwwqLDvuKAok4uLEfFocO1wq/Cr8K8SGtpHVJrLOKAmifDrQfDpkbDsx7DvF
DDocOnY8KN4oCTxaHDsl0+77+9f8KQw4zigJzDjeKAnh3DmV4EWx89MsK2wp3Co
QPigLp1xaHDu3c6wrTigJhbwo83EloQwo0GEj3Du8OlWsOAPMO14oCYw7TDgcO8
wrohw6PDqnckw7HDkATigqwiw7gsbBvCs++/vWhSa13DjsOMIXgP77+9HSHCvSp
EP8KPKyPigJzDn+KAosOb4oCd77+9bkPDkSUKwr/CjcKzWw4rLizDkeKAuRvDtx
LDv+KEosK8wq/CvMKufAlowoFX4oCTw5jDssOnNsOGw51MP8OU4oKsH8WTwr8qf
i3CsMOmw6IHw708euKAsGs1I8Ox4oCgFMKuLTzDpnph4oCecMKmaHTCoHhRwqTD
rQXDryXCgcObfloffnJsQAsqwq7Dk8ucwrXCsMONWcK6wq4gw7zCs8KwSBzDvsK
mwqPCt38sSXtawqdWOlYUw7vCpMOhdMKtCuKAkwYZ4oCUw7Z5DOKAmeKAnMOyw4
fDkD7DocOzw4xcPsKiw4VVAeKCrBTDpEBwwrXDssOzw7kUPcOKDyVPw6BZw4XDk
CBqw419w6rDhcOjwqJrGcKww7LDnlvGkiFM4oKsf8ODwqZqak3igLnCtFoiwrzL
hsKn4oSiUcKgxaESwrvCr8O4S8OIw4ZLw6LDp8aSRcK54oCaBcOGxbjCpOKAphD
DljLDmsKkw7fDscObw6wsw5DCtEc2GMK0IRLFk8K0TAp/XcOcw67CjTFGbWjDgM
ONwq7FveKAoGfDi8OKeMO1KAXDsMKjHX3CtUtKCcOFW08Xw5/DnMOzEMK+YRjDk
sOQwqs2enB4ZhbDvnFJxZPCswXigLBUxaA4
-----END CERTIFICATE-----
Certificate bag
Bag Attributes: <Empty Attributes>
subject=C = ES, ST = YYYYYYYYY, L = XXXXXXXX, O = example, CN = example.com
issuer=DC = COM, DC = MYORG, CN = MYORG-AD01-CA
-----BEGIN CERTIFICATE-----
MOKAmgXCpjDigJoDxb3CoAMCAQICE0nvv73vv73vv73LnMKgG8Kqw5JEdOKAusK
/77+977+977+977+977+9y5wwCgYJKuKAoEjigKDDtwoBAQoF77+9MFcxEzARBg
oJ4oCZJuKAsOKAnMOyLGQBGRYDQ09NMRwwGgYKCeKAmSbigLDigJzDsixkARkWD
E1ZT1JHMSIwIAYDVQQDExlNWU9SRy1BRDAxLUNBMB4XCjI0MDUyMjE4NTcyNVoX
CjI1MDUyMjE5MDcyNVowXDELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCVlZWVlZWVl
ZWTERMA8GA1UEBxMIWFhYWFhYWFgxEDAOBgNVBAoTB2V4YW1wbGUxFDASBgNVBA
MTC2V4YW1wbGUuY29tMOKAmgEiMAoGCSrigKBI4oCgw7cKAQEBBe+/vQPigJoBD
++/vTDigJoBCgLigJoBAe+/vcOrw6TigKZMwqZ3wroyawPCpHPigLnCpMOhwrjD
ujTigJ3DssO3CsKjOSPDs+KAmsK3V8Ocwq93asKvCMK1w5N+EXkRHuKAnRoXN8O
0W2NkCU8tw7bDl+KAsMOv4oCw77+9d8OSbnXCv11T4oCwYXjigJ7CpcOI4oCgwq
REVwpGw73igLAtNEJEwrBOw4daLkfCsE5qDsOKcWho4oCTw5Jdw75dNFJUIsKQw
5HDq8OxwoHigJ12OBUlw6/Dt8K14oCecMK8xbh9xaAMwrzCqMO3X8KgMg/CqFLD
mcK2XsOHZSDDrMO3QA5kR8K+xZLDluKAouKAsFR9IcK9xpIoNOKAnikwd+KAmcO
Ew7EwCHjCsMuGDMaSw5DFuMOySsKN4oCew7ItUwopLDnCou+/vcOTxpLigqxeKD
nDsktIRR1OX2vCtcOfWMOUw6/Cs8K7YmvDlU7DmcOtw4DDinbCsBxnBU7igLBHE
eKAmSvCq8OzKMKlw5BcRQcDXRXigJhJw7ElwqrDgGU+ReKApuKAoThqSwcdAgMB
77+9AcKj4oCaAWQw4oCaAWAwHQYDVR0OBBYEFMW4O+KAmMOA4oCgCD7Dh8K3EcK
tWCXDonDDgk0Cw7fDozArBgNVHRHDhCQwIuKAmgtleGFtcGxlLmNvbeKAmhN0ZX
N0aW5nLmV4YW1wbGUuY29tMB8GA1UdIwQYMBbigqwUPwfDtgbDn2TDicK9cuKAm
FvDjh/igKIGX8O1wqZMw7YwXQYDVR0fBFYwVDBSwqBQwqBO4oCgTGZpbGU6Ly8v
L0FEMDEuTVlPUkcuQ09NL0NlcnRFbnJvbGwvMMK1FTkVSMK1BRDDgMOEwrUKBFT
DpFUkwrQUdMOEw7QkFS5jcmwwwoHGkgYIKwYBBQUHAQEEdzB1MHMGCCsGAQUFBz
AC4oCgZ2ZpbGU6Ly8vL0FEMDEuTVlPUkcuQ09NL0NlcnRFbnJvbGwvQUQwMS5NW
U9SRy5DT01fTVlPUkctQUQwMS1DQS5jcnQwDAYDVR0TAQHDvwQCMO+/vTAKBgkq
4oCgSOKAoMO3CgEBCgXvv70D4oCaAgHvv705XsK6w4Jrwo3igJ1cJ+KAoi3DlMK
hw7EbMV7igJTCoGvigKLDhMO+w6ZaDnfDusOCw4Zpw6NiFOKAne+/vWbDiVfDhc
K8w5vDjlXigJjCjcKmeMOtb8K4LTBPw5XCrMOMFjpqccOHw4Q4MOKAnhXDj3/Dh
W8QY8KsTDPGknFPw6d5wrDDnsKlxZLDiwrigJpFwrTigLrCucW9KnJ1b8K5wrkd
4oCwwrLDtCpEwrbigJ5Yw7vDv1NFUQbCreKAnuKAosKlwqcdYmXCrcKgwqXDpVI
PccO7Wj7igJMrw7fFvcORXMOLw6paV3hMw6dpwrzCpWEPw6Iewq3DiMOSOBsPw4
TDnMKBw47CpeKAlOKAoMOWw43ihKLDlcK8AsOrU8Ofa8OiKMOdxZLDlsOMw5Pig
JlTw4PCkBDigLDFk8OrZAHigKEBTsK9wo/igJgYenPDo27DqeKEosKhMwTCtifD
n3R8YcKtw71dw6/igJ0rxZJyw4HFveKEosOoc+KAky5Zw6TDk30+H2zCgcKvwpA
YxpLCncO6fwdpwqXigJTCusOdw7hDfmY8b0PDhXILw5zigKbDgsO+X8KwBm3Cpn
zCrHx1w4zDmG/CvMOyw6TCo07igLnDq2AEw64bVDvCtVPDgxrDu3nCtsKiw5TCp
MKsw5pbw4YgISXCqGtRGsO94oC6bDDigJrDieKAoeKAlMK9w68I4oCwwrLDgGw6
wrURfcOxw78Exb0Kw7F8wrgoXHzCvMKww7fDoXZqw5MWLsO+w7J4bcucWuKAosO
CVktAwrJFHsOCcsKgxpLFksOB4oCYbuKApjd3VVAmFj99xaEZw4cPw7HCvkwIY8
OZw6jFvcOuDAPDsU5Gw6JswrjFkiPDoMKvFMKPwqJBwqrigJPDu8K+ZuKApj8aw
5Mhwr0IThLDmEPCqzXCsRFZTMOkaj3DtR7CpknDsGUt4oSic8uGw5Qac8O2w60m
wrEQw7964oSiPjvigLDigKLDpFfDvsOxPOKAmXHFoHleAsKpw6jDoivDsHPCvEY
rwrFPw6cJw5bDtWbCkMO5VcOLxaDDtDVhw6NZ4oKswqcy4oCdw7XCr1sWw6DDrM
O6w4nCjcOkwq3CpA==
-----END CERTIFICATE-----

I've tried this python code

with open(p12_file_path, 'rb') as pfxFile:
        (privatekey, certificate, cas) = pkcs12.load_key_and_certificates(pfxFile.read(), p12_password.encode('utf-8'))

and privatekey and certificate are None, while cas containes my CA data and my hostname data.

print(privatekey)
print(certificate)
print(cas)


None
None
[<Certificate(subject=<Name(DC=COM,DC=MYORG,CN=MYORG-AD01-CA)>, ...)>, <Certificate(subject=<Name(C=ES,ST=XXXXXXX,L=YYYYYY,O=ffff,CN=ffff)>, ...)>]

What am I doing wrong?

Update:

openssl req -new -nodes -newkey rsa:2048 -keyout $certKey -out $certCsr -config $certCfg

certreq -config $AuthorityCertificatesServer -submit $certCsr | Select-String 'Id. de solicitud: (\d+)' | ForEach-Object { $_.Matches.Groups[1].Value }" -OutVariable ID_SOLICITUD

certutil -resubmit $ID_SOLICITUD

For now I've stopped here, if I don't do certutil -resubmit my certificate stays in pending in the certsrv window and certreq -accept does nothing, if I do certutil -resubmit it automatically goes to Issued Certificates on certsrv (Do I even need the following commands then?).

Not sure about the order of the following:

certreq -accept -user -config $($AuthorityCertificatesServer) $certRsp

certreq -config $AuthorityCertificatesServer -retrieve $ID_SOLICITUD $certRsp $certP7b

openssl pkcs7 -in $certP7b -print_certs > $certPem


Output of certutil.exe -dump -split <file>

Mensaje PKCS7/CMS:
  CMSG_SIGNED(2)
  CMSG_SIGNED_DATA_CMS_VERSION(3)
  Tipo de contenido: 1.3.6.1.5.5.7.12.3 Respuesta de CMC

Contenido de mensaje PKCS7:
================ Iniciar nivel de anidación 1 ================
Respuesta CMS:
Atributos etiquetados: 1

  Id. de cuerpo: 1
  1.3.6.1.5.5.7.7.1 Información de estado de CMC
  Valor[0]:
    Información de estado de CMC: CMC_STATUS_PENDING(3)
    Referencia de Id. de cuerpo[0]: 1
    Cadena de estado: Tomada bajo proposición
    Otra elección de información: CMC_OTHER_INFO_PEND_CHOICE(2)
Token pendiente:    0000  c2 00 00 00                                        ....
     Tiempo pendiente 24/05/2024 14:41


Información del contenido etiquetada: 0
Otros mensajes etiquetados: 0
----------------  Finalizar nivel de anidación 1  ----------------

Contador de firmantes: 1
No se confía en ninguno de los firmantes del mensaje criptográfico o de la lista de certificados de confianza. 0x8009202b (-2146885589 CRYPT_E_NO_TRUSTED_SIGNER)
No se confía en ninguno de los firmantes del mensaje criptográfico o de la lista de certificados de confianza. 0x8009202b (-2146885589 CRYPT_E_NO_TRUSTED_SIGNER)

Información de firmante[0]:
CMSG_SIGNER_INFO_PKCS_1_5_VERSION(1)
CERT_ID_ISSUER_SERIAL_NUMBER(1)
    Número de serie: 63feb01c81d64f924760ca5c27c1cc15
    Emisor: CN=MYORG-AD01-CA, DC=MYORG, DC=COM
Algoritmo hash:
    Id. de objeto del algoritmo: 2.16.840.1.101.3.4.2.3 sha512 (sha512NoSign)
    Parámetros de algoritmo: NULL
Algoritmo hash cifrado:
    Id. de objeto del algoritmo: 1.2.840.113549.1.1.1 RSA
    Parámetros de algoritmo: NULL
Hash cifrado:
    0000  a9 d1 7e e9 ff 40 39 30  ee 7a b7 44 f6 49 05 ea
    0010  79 62 30 11 cf fa 97 d5  40 da b8 60 ff 43 8a f7
    0020  d1 8a 7e 89 2b 56 07 f1  5d 6b 27 3d a9 cd 91 fb
    0030  cc 5a 50 12 49 7f 77 9a  0c d0 4b bb 37 e1 e7 7e
    0040  95 5d d7 1f a4 62 c9 58  b3 65 ea 3f 19 d9 a1 e3
    0050  92 24 80 57 4a 46 4c 39  ff 8b f5 fd af 9e 65 f9
    0060  4e 04 95 f3 91 89 7e 5d  52 c5 b2 9f 3c 53 17 ad
    0070  78 d5 d6 26 43 00 ac e5  f6 67 cb 3a 28 6f bf c8
    0080  ba f0 ea 9f 2d 76 cc bd  f2 34 02 40 05 19 2c c7
    0090  a0 2b 6e 74 e5 06 80 56  4b ed ff cc 23 aa 0e 5a
    00a0  1c ed 99 30 c2 18 20 fb  56 5f 7c 76 7e 84 34 9e
    00b0  ed 0a 97 75 82 e2 bc ac  4d 78 85 66 85 d1 21 87
    00c0  e7 ed b5 48 f4 2d 48 d3  68 71 85 60 ae 66 c3 c6
    00d0  84 6a e7 be 4a 50 ad 82  5e 31 75 ea 27 bb 21 d3
    00e0  a5 c8 58 1c 6b 81 e2 bd  c5 ac 9e eb 40 d2 2d 00
    00f0  ab 7f 74 2a 62 ca 85 f3  80 4e 85 92 7e f3 ec 9c
    0100  01 d7 59 82 19 2e 09 6e  1e c5 82 01 78 e2 f8 75
    0110  6c e0 d8 d6 95 47 06 a1  a9 95 56 f3 86 b6 82 3a
    0120  2d 21 b1 81 c1 5e 65 58  f9 cc ad f7 88 d9 d1 64
    0130  fe d0 71 36 9a d7 b1 33  3a 70 fd 49 7d ce 83 28
    0140  f8 58 eb 57 ac 3a bf 9a  15 82 e6 11 9a 4c f2 ab
    0150  06 26 3d 9e ec eb 78 7f  4d 7e 9f fa 6d fe 4f 41
    0160  d9 41 f0 17 0c 4f 58 9d  57 b0 cc b4 16 1f 2e 95
    0170  27 a5 77 55 f4 fd a2 b6  4a f4 8c 61 0d 66 99 68
    0180  d0 7b bf 4a 2e 83 89 ff  c6 8a 86 38 d7 01 c2 19
    0190  c4 7c 77 7c 89 bd 82 32  2b 6a 22 ef 94 48 08 1f
    01a0  32 f1 4e 18 22 e5 a8 99  d3 f1 79 fe a3 51 79 1c
    01b0  cd 7a 36 28 3b f6 a8 ac  e3 76 aa b1 22 29 9b d8
    01c0  1d 84 1a b3 20 0b 72 26  f4 c0 28 1b 0e bd 6e da
    01d0  b2 2f d3 a3 d2 ae 1e c5  b3 13 b8 18 29 db f1 9e
    01e0  b7 d5 4c 79 ec 78 89 d4  95 ba 0a ec f7 ae dc cb
    01f0  94 5e b5 64 93 46 e9 d7  bd 4c 63 85 6b 62 f3 49

Atributos autenticados[0]:
  2 atributos:

  Atributo[0]: 1.2.840.113549.1.9.3 (Tipo de contenido)
    Valor[0][0], Longitud = a
    1.3.6.1.5.5.7.12.3 Respuesta de CMC

  Atributo[1]: 1.2.840.113549.1.9.4 (Síntesis del mensaje)
    Valor[1][0], Longitud = 42
    Síntesis del mensaje:
        0072197ea46d7b12e77c687b70db82488626e206e703fbe3ef6da2fdeb832f36d8cd2ad446aab57429e32b505c5e557e14191692403fdbadf1ea2b2f9cc51f42

Atributos no autenticados[0]:
  0 atributos:

Algoritmo hash calculado: 9b1099cc47c2abcee33e791bf254ec6b0cb75ff20149e4a7e86b63fbb3c0ad59c6b5783c1e9c796417eeba3e28917837e8f166ec4ff8432b9c54210d32a4e0a3
Sin destinatario
Algoritmo hash calculado: 9b1099cc47c2abcee33e791bf254ec6b0cb75ff20149e4a7e86b63fbb3c0ad59c6b5783c1e9c796417eeba3e28917837e8f166ec4ff8432b9c54210d32a4e0a3

No hay certificados
No hay CRLs

6
  • Why do you need a PKCS#12. Apache expects a private key in PEM format as well as a PEM certificate chain, which you're extracting from the PKCS#12 anyway. Maybe explain exactly what you're trying to do here - what you're doing seems very long winded. Commented May 22 at 20:27
  • I have a Windows Server with certsrv, certreq and certutil, and once I have the certificate issued I want to export it to be used on apache, I don´t care about the format as long as it's usable by apache.
    – Daviid
    Commented May 23 at 6:33
  • Do you have to use scripts? Can you use the MMC instead? certlm.msc. It would also be easier to create the private key and CSR using openssl, then submit the CSR to the CA. Commented May 23 at 6:38
  • I'd like the process to be automated and as simple as possible, I'm the only IT guy so if someone ever needs to do this running a script and entering hostname.com would be preferred.
    – Daviid
    Commented May 23 at 6:58
  • 1
    certreq.exe -accept retrieves the certificate and places it in your Windows cert store, which isn't what you need. certreq.exe -retrieve simply retrieves it and saves it to a file, which is what you need in order to pass it to Apache (after some further processing). Commented May 24 at 12:09

1 Answer 1

2

1st, create an OpenSSL configuration file for the certification request. Note that the content of the req_dn and alt_names is irrelevant if the template you choose is setting the Subject information from Active Directory.

# C:\Apache24\certificates\openssl.cnf

prompt             = no
distinguished_name = req_dn
req_extensions = req_ext

[ req_dn ]
countryName = ES
stateOrProvinceName = xxxx
localityName = yyyy
organizationName = zzz
organizationalUnitName = IT Dept
commonName         = Example Web Server

[ req_ext ]
subjectAltName = @alt_names

[alt_names]
DNS.1 = www.example.org
DNS.2 = example.org
IP.1 = 192.168.10.162

Create the CSR:

cd C:\Apache24\certificates\
openssl req -new -newkey rsa:2048 -keyout privatekey.pem -out apache.req -config openssl.cnf

Submit the request to the CA (adjust the template name as appropriate for your environment):

certreq.exe -attrib "CertificateTemplate:WebServer" apache.req

Take a note of the Request ID returned - you'll need this to help find the request on a busy CA.

Ask the CA Certificate Manager to review/approve the request.

Once approved, retrieve the certificate with:

certreq.exe -Retrieve <Request ID> apache.rsp apache.p7b

The privatekey.pem is the file (with path) that should be pointed to by Apache's SSLCertificateKeyFile option and apache.rsp can be ignored.

Convert the P7B to a chain with:

openssl pkcs7 -in apache.p7b -print_certs > apache.pem

The output (apache.pem) is the certificate chain file (with path) that should be pointed to by Apache's SSLCertificateFile option.

6
  • Thanks, I'm trying right now, would you happen to know why after "certreq -submit" my last path $certCrt that should be .crt gets its extension changed to .rsp? Invoke-Expression -Command "openssl req -new -nodes -newkey rsa:2048 -keyout $certKey -out $certCsr -config $certCfg" Invoke-Expression -Command "certreq -submit -config $AuthorityCertificatesServer $certCsr $certCrt | Select-String 'Id. de solicitud: (\d+)' | ForEach-Object { `$_.Matches.Groups[1].Value }" -OutVariable ID_SOLICITUD
    – Daviid
    Commented May 23 at 9:25
  • I must be doing something wrong, echo "certreq -config $AuthorityCertificatesServer -submit $certCsr $certRsp $certP7b $certFull" gives me certreq -config localhost\MYORG-AD01-CA -submit C:\Users\daviid\AppData\Local\Temp\1\example.com\example.com.csr C:\Users\daviid\AppData\Local\Temp\1\example.com\example.com.rsp C:\Users\daviid\AppData\Local\Temp\1\example.com\example.com.p7b C:\Users\daviid\AppData\Local\Temp\1\example.com\example.com.full but at the end I only have example.com.full and opening it just looks like a simple certificate ---BEGIN CERTIFICATE--- xx ---END CERTIFICATE---
    – Daviid
    Commented May 24 at 9:01
  • Updated main post with my current situation
    – Daviid
    Commented May 24 at 9:36
  • 1
    What looks like a "simple certificate" could be a PKCS#7 (or P7B for Microsoft). What happens if you run certutil.exe -dump -split <file> against it (in an empty folder preferably)? Commented May 24 at 12:06
  • 1
    You're going to fail if you give this script to some 'run' team. They'll fail when they try to run certutil.exe -resubmit <req ID> as they are not CA Certificate Managers. If you give them that role, then your PKI is not going to be trustworthy. Commented May 24 at 13:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .