First, to be clear, PS New-SelfsignedCertificate
does three things: it creates a keypair in the Windows store, it creates a selfsigned cert for that keypair, and it stores the cert with the keypair in the store. Although creating the cert is the more complicated step of this process, by itself it would be useless; the cert can only be used in combination with the privatekey from the keypair.
You can do it with PS. As you found, -TextExtension
doesn't seem to have a text format for AIA and needs the value to be encoded; in general ASN.1 encoding can be moderately complicated, but this case (AIA containing single OCSP) isn't too bad if the URL is not more than 113 characters (assuming I've counted correctly):
$s=[System.Text.Encoding]::Default.GetBytes("http://myca/onlinestatus")
[byte[]]$t=(43,6,1,5,5,7,48,1)
$t=(6,$t.length)+$t+(0x86,$s.length)+$s
$t=(48,$t.length)+$t
$t=(48,$t.length)+$t
$e=[Convert]::ToBase64String($t)
New-SelfSignedCertificate -dnsname example.org -certstore cert:\currentuser\my -TextExtension ("1.3.6.1.5.5.7.1.1="+$e)
If you want to use the same OCSP for all (or at least multiple) certs, you can do the first block once, save the encoding and re-use it where needed.
Or with OpenSSL, probably. You can (definitely) use OpenSSL to create a self-signed cert containing extension(s) 5 ways, all of them including the AIA extension and OCSP element, and all of them either creating a new keypair or using an existing one:
directly, with
openssl req [-config $cfile] {-newkey $parms -keyout $kfile [-nodes]|-new -key $kfile} [-subj $dname] -x509 [-days $n] [-$hash]
.
This can use extensions from the configfile or in 1.1.1 only specified with -addext
, as per the man page which links to the man page for x509v3_config for extensions (v3 was the version of X.509 that first defined extensions). Here you want authorityInfoAccess=OCSP;URL:http://myca/whatever
.
create a CSR containing the desired extension(s) with openssl req {as above through -subj}
and then create a cert for that CSR using openssl ca
configured with copy_extensions=yes
(which is not the default at least if using upstream) and other settings and/or options as needed.
create a CSR which does not need to (and for clarity should not) contain the desired extension(s) and then create a cert for that CSR using one of the following which adds the extension(s):
3A. openssl req [-in $file else redir or pipe] -key $kfile [-config $cfile] [-extensions $sect|-addext ...] -x509 [-days $n] [-$hash]
3B. openssl x509 -req [-in $file else redir or pipe] -signkey $kfile -extfile $xfile [-extensions $sect] -days $n [-$hash]
3C. openssl ca
not configured with copy_extensions=yes
(Yes that format is bad; I spent about 15 minutes trying to get markdown to do it without success. If anyone knows how to do it right please edit.)
All of these are subject to the OpenSSL limitation that it uses only keys (and also certs) in PEM files and does not read from or write to the Windows store. If you want to use this keypair/cert with a Windows-based app like IIS, IE or Edge, or almost anything in dot-net by default, it won't work. You need to either (1) create the keypair and cert in OpenSSL, pack into a PKCS12 (aka PFX) with openssl pkcs12 -export
, and import the PKCS12 to Windows or (2) create the keypair (and possibly a dummy cert) in Windows, export the key from Windows to a PKCS12 and convert to OpenSSL's PEM format, use OpenSSL to create the cert, and import the cert back to Windows.
But I don't know why you want to. No relier will ever use the AIA (either OCSP or caIssuer) on a selfsigned certificate. A selfsigned certificate is expected to be a root, and thus it cannot be revoked by its parent -- it has none. A selfsigned cert can only be trusted by manually adding it to the truststore (either systemwide or specialized) and can only be distrusted by manually removing it (or disabling it if the truststore supports that).