STRONGSWAN_PKI---OCSP(1)

πŸ“¦
version 6.0.7 Β· 4 versions
, in fedora 43, fedora 44

πŸ’– pki --ocsp β€” the strongSwan pki(1) manual, but make it make sense πŸ’–

okay bestie, welcome to PKI --OCSP(1), aka the strongSwan girlies' guide to OCSP. grab a boba, we're parsing requests and clapping back with responses. πŸŽ€


✨ NAME ✨

pki --ocsp β€” OCSP request parser and OCSP responder. that's it, that's the vibe. πŸ’…


🌸 SYNOPSIS 🌸

pki --ocsp [--in file] [--cacert file] [--debug level]

pki --ocsp --respond [--in file] --cacert file [--key file|--keyid hex]
           [--cert file|--certid hex] [--index file]
           [--lifetime minutes] [--digest digest]
           [--rsa-padding padding] [--debug level]

pki --ocsp --options file

pki --ocsp -h | --help

πŸ¦‹ DESCRIPTION πŸ¦‹

so this is one of the sub-commands of pki(1), and she has two moods. mood one: she parses an Online Certificate Status Protocol (OCSP) request, as defined by RFC 6960. mood two: you pass her the --respond option and she generates an OCSP response based on that OCSP request. main character energy fr.

now, where does the certificate status come from? lowkey it can be provided by plugins. so if you're not using the --index option, this currently requires the openxpki and mysql plugins in order to directly access the internal certificate database of an OpenXPKI (https://openxpki.org) server. iykyk. no cap. πŸ’€


πŸ‘‘ OPTIONS πŸ‘‘

  • -h, --help β€” prints usage info plus a little summary of all the options available. your lil cheat sheet. 🫢
  • -v, --debug level β€” sets the debug level. default: 1.
  • -+, --options file β€” reads command line options from a file. fancy.
  • -i, --in file β€” the OCSP request. if you don't give her one, the OCSP request gets read from STDIN. she'll wait. patiently. πŸ’…
  • -C, --cacert file β€” a CA certificate corresponding to one of the issuer hashes contained in the OCSP request. and if the OCSP request is signed, this is a CA certificate forming the trust chain. can be used multiple times. stack 'em up bestie. 🧚
  • -k, --key file β€” the OCSP signer key. can be used multiple times.
  • -K, --keyid hex β€” smartcard or TPM 2.0 OCSP signer key object handle. can be used multiple times.
  • -c, --cert file β€” the OCSP signer certificate (if it's not a CA certificate). can be used multiple times.
  • -X, --certid hex β€” smartcard or TPM 2.0 OCSP signer certificate object handle. can be used multiple times.
  • -x, --index file β€” an OpenSSL-style index.txt giving you info about the status of certificates issued by the CA certificate loaded immediately before. can be used multiple times if you need the status for multiple CAs β€” just make sure you pass each index.txt file right after the corresponding CA certificate. order matters, bestie, it's giving choreography. πŸŽ€

the structure of these files is described below, keep scrolling. πŸ‘‡

  • -l, --lifetime minutes β€” validity in minutes of the OCSP response. if it's missing, nextUpdate is omitted. gone. not invited to the party. πŸ™ˆ
  • -g, --digest digest β€” the digest to use for signature creation. one of md5, sha1, sha224, sha256, sha384, or sha512, sha3_224, sha3_256, sha3_384, sha3_512. the default is determined based on the type and size of the OCSP signing key. she picks for you. πŸ’–
  • -R, --rsa-padding padding β€” the padding to use for RSA signatures. either pkcs1 or pss, defaults to pkcs1.

πŸ“œ INDEX.TXT DESCRIPTION πŸ“œ

each line in an index.txt file has six columns, separated by tab characters. not spaces. tabs. do not come at me with spaces. 😭

column one is the certificate status, and it can be:

  • "V" β€” for valid
  • "E" β€” for expired, which is treated like valid (we don't judge, expired is valid's cousin)
  • "R" β€” for revoked

column two is the certificate's expiration date and time in UTC, formatted as YYMMDDHHMMSSZ. this field gets ignored by the command, but it must not be empty. like, it has to be there. it just doesn't get read. it's the friend who shows up to the group photo and gets cropped out. πŸ’€

column three is the revocation date and time in UTC, formatted as YYMMDDHHMMSSZ, plus an optional revocation reason that immediately follows it, separated by a comma. valid reasons are:

  • "keyCompromise"
  • "CACompromise"
  • "affiliationChanged"
  • "superseded"
  • "cessationOfOperation"
  • "certificateHold"
  • "removeFromCRL"

any other value, or just omitting a reason entirely, results in "unspecified". it's the default. she said unspecified and meant it. ✨

column four is the certificate's serial number in hexadecimal encoding.

columns five and six are both ignored by the command, so honestly they may be omitted completely. when they are there, they can contain a path to the certificate (usually set to "unknown") and the certificate's subject DN with slashes separating the RDNs. optional queens. πŸ‘‘


🌈 example index.txt 🌈

V    310930122422Z       03  unknown /C=CH/O=strongSwan/CN=moon...
V    310930122422Z       04  unknown /C=CH/O=strongSwan/CN=sun...
R    310930122422Z   231002122422Z,keyCompromise 88
V    Z       05
note that the fields are separated by tabs. so if a certificate is valid, two tabs follow after the expiration date. the third line in this example only specifies the relevant first four columns, and the fourth even uses a dummy expiration date. she's chaotic but she's valid. πŸ§šβ€β™€οΈ

to be continued, bestie… part 2 incoming πŸ’œ

✨ EXAMPLES ✨

okay bestie, this is the part where it all clicks πŸ’… every single one of these is a real thing you can type, so buckle up.


🌸 peep the raw content of an OCSP request

first up: just look at what's inside an OCSP request. no response, no signing, just vibes and bytes.

pki --ocsp --in req_ca.der

nonce:               5b:14:e3:cc:d5:b2:65:ec:c4:0d:c3:11:37:6a:9d:71
  issuerKeyHash:     b6:76:79:95:b5:58:..:06:93:f3:39:79:19 (no match)
  issuerNameHash:    af:25:78:ce:fc:15:..:67:95:81:31:a3:4d (no match)
  serialNumber:      4f:33:21:1d:4d:fd:9b:db
  issuerKeyHash:     b6:76:79:95:b5:58:..:06:93:f3:39:79:19 (no match)
  issuerNameHash:    af:25:78:ce:fc:15:..:67:95:81:31:a3:4d (no match)
  serialNumber:      68:f2:93:10:65:d0:5e:d1

see those (no match) notes? that's because no issuer cert was handed over, so nothing could be matched up. it's giving "who dis" 😭


πŸ¦‹ same request, but now you hand over the issuer cert

watch what happens the second you pass --cacert:

pki --ocsp --in req_ca.der --cacert cacert.pem

nonce:               5b:14:e3:cc:d5:b2:65:ec:c4:0d:c3:11:37:6a:9d:71
issuer:             "C=CH, O=strongSwan Project, CN=strongSwan Root CA"
  issuerKeyHash:     b6:76:79:95:b5:58:..:06:93:f3:39:79:19 (ok)
  issuerNameHash:    af:25:78:ce:fc:15:..:67:95:81:31:a3:4d (ok)
  serialNumber:      4f:33:21:1d:4d:fd:9b:db
issuer:             "C=CH, O=strongSwan Project, CN=strongSwan Root CA"
  issuerKeyHash:     b6:76:79:95:b5:58:..:06:93:f3:39:79:19 (ok)
  issuerNameHash:    af:25:78:ce:fc:15:..:67:95:81:31:a3:4d (ok)
  serialNumber:      68:f2:93:10:65:d0:5e:d1

matched, matched, matched ✨ the hashes now say (ok) and the issuer gets a whole name reveal moment. main character energy fr.


πŸŽ€ responding to it, signed by the CA itself

now we actually respond. the CA signs its own OCSP response here, and we pipe the DER straight into rsp_ca.der:

pki --ocsp --respond --in req_ca.der --cacert cacert.pem --key cakey.pem \
           --lifetime 10 > rsp_ca.der

nonce:               5b:14:e3:cc:d5:b2:65:ec:c4:0d:c3:11:37:6a:9d:71
issuer:             "C=CH, O=strongSwan Project, CN=strongSwan Root CA"
  issuerKeyHash:     b6:76:79:95:b5:58:..:06:93:f3:39:79:19 (ok)
  issuerNameHash:    af:25:78:ce:fc:15:..:67:95:81:31:a3:4d (ok)
  serialNumber:      4f:33:21:1d:4d:fd:9b:db
  thisUpdate:        Oct 19 15:54:15 UTC 2023
  nextUpdate:        Oct 19 16:04:15 UTC 2023
  certValidation:    GOOD
issuer:             "C=CH, O=strongSwan Project, CN=strongSwan Root CA"
  issuerKeyHash:     b6:76:79:95:b5:58:..:06:93:f3:39:79:19 (ok)
  issuerNameHash:    af:25:78:ce:fc:15:..:67:95:81:31:a3:4d (ok)
  serialNumber:      68:f2:93:10:65:d0:5e:d1
  thisUpdate:        Oct 19 15:54:15 UTC 2023
  nextUpdate:        Oct 19 16:04:15 UTC 2023
  certValidation:    GOOD
trusted signer:     "C=CH, O=strongSwan Project, CN=strongSwan Root CA"
ocspResponseStatus:  successful

thisUpdate is when it was stamped, nextUpdate is when it goes stale (that's your --lifetime 10 doing its thing πŸ’…), and both certs are GOOD. the trusted signer is the Root CA, and ocspResponseStatus: successful β€” we ate, no crumbs. πŸ‘‘


🌈 signed request, full trust chain, let's go

here the request is signed by the requestor, and we feed in the complete chain so it can be verified all the way up to the root:

pki --ocsp --respond --in req_signed.der --cacert cacert.pem --cacert issuer1.pem \
           --key signerKey1.pem --cert signerCert1.pem --lifetime 10 > rsp_signed.der

requestor:          "C=CH, O=strongSwan Project, CN=vpn.strongswan.org"
  using certificate "C=CH, O=strongSwan Project, CN=vpn.strongswan.org"
  using trusted intermediate ca certificate "C=CH, O=strongSwan Project, CN=strongSwan Issuing CA 1"
  using trusted ca certificate "C=CH, O=strongSwan Project, CN=strongSwan Root CA"
  reached self-signed root ca with a path length of 1
requestor is trusted
nonce:               a8:0f:29:0f:08:9c:29:c1:0d:a8:cb:b0:21:fa:e1:f7
issuer:             "C=CH, O=strongSwan Project, CN=strongSwan Issuing CA 1"
  issuerKeyHash:     5a:1b:ec:17:f0:6d:..:a2:c8:e7:6a:84:20 (ok)
  issuerNameHash:    df:1e:24:71:96:e6:..:b9:82:18:45:e7:09 (ok)
  serialNumber:      04:ff:cc:8d:36:91:cb:35:d7:c4
  thisUpdate:        Oct 19 16:30:54 UTC 2023
  nextUpdate:        Oct 19 16:40:54 UTC 2023
  certValidation:    REVOKED
  revocationTime:    Mar 26 06:41:54 UTC 2023
  revocationReason:  superseded
trusted signer:     "C=CH, O=strongSwan Project, CN=OCSP signer of strongSwan Issuing CA 1"
ocspResponseStatus:  successful

the requestor's chain gets walked step by step β€” leaf β†’ trusted intermediate β†’ trusted root β†’ reached self-signed root ca with a path length of 1, and then requestor is trusted 🫢

but hold up, look at the cert itself: certValidation: REVOKED 😭 with a revocationTime and revocationReason: superseded. that's not a bug, that's the actual answer β€” the cert is revoked, and the response says so. the signer is the OCSP signer of strongSwan Issuing CA 1, and status is still successful (because responding successfully β‰  saying the cert is fine, bestie).


πŸ’€ two items, two issuers, one signer

this one's spicy. the request has two items from two different known issuers, and each issuer has its own OCSP signer. plot twist: the issuer of the first request item decides which OCSP signer gets used to sign the whole response.

pki --ocsp --respond --in req.der --cacert issuer1.pem --cacert issuer2.pem \
           --key signerKey1.pem --cert signerCert1.pem \
           --key signerKey2.pem --cert signerCert2.pem \
           --lifetime 10 > rsp_trusted.der

nonce:               a1:33:aa:bc:96:60:69:76:f3:bc:9c:88:3b:07:50:47
issuer:             "C=CH, O=strongSwan Project, CN=strongSwan Issuing CA 2"
  issuerKeyHash:     72:41:ca:f9:35:87:..:d3:83:ab:d5:89:7b (ok)
  issuerNameHash:    5e:b2:b4:42:e1:a5:..:b2:c3:9a:38:4f:cd (ok)
  serialNumber:      29:ff:36:d9:9a:21:49:61:91:1d
  thisUpdate:        Oct 19 16:02:35 UTC 2023
  nextUpdate:        Oct 19 16:12:35 UTC 2023
  certValidation:    REVOKED
  revocationTime:    Sep 22 13:13:04 UTC 2023
  revocationReason:  superseded
issuer:             "C=CH, O=strongSwan Project, CN=strongSwan Issuing CA 1"
  issuerKeyHash:     5a:1b:ec:17:f0:6d:..:a2:c8:e7:6a:84:20 (ok)
  issuerNameHash:    df:1e:24:71:96:e6:..:b9:82:18:45:e7:09 (ok)
  serialNumber:      10:ff:45:9a:6d:ee:4c:ec:7c:97
  thisUpdate:        Oct 19 16:02:35 UTC 2023
  nextUpdate:        Oct 19 16:12:35 UTC 2023
  certValidation:    FAILED
there are multiple known issuers
trusted signer:     "C=CH, O=strongSwan Project, CN=OCSP signer of strongSwan Issuing CA 2"
ocspResponseStatus:  successful

note the there are multiple known issuers line β€” that's it flagging that it had choices to make πŸ™ˆ and the trusted signer ended up being the signer of Issuing CA 2, because item one belonged to CA 2. the second item's validation came back FAILED, which is just what it is.


πŸ™ˆ same thing again, but with a self-signed OCSP signing cert

round two of that same response, except now the signing cert is self-signed:

pki --ocsp --respond --in req.der --cacert issuer1.pem --cacert issuer2.pem \
           --key signerKey.pem --cert signerCert.pem --lifetime 10 > rsp_self_signed.der

nonce:               a1:33:aa:bc:96:60:69:76:f3:bc:9c:88:3b:07:50:47
issuer:             "C=CH, O=strongSwan Project, CN=strongSwan Issuing CA 2"
  issuerKeyHash:     72:41:ca:f9:35:87:..:d3:83:ab:d5:89:7b (ok)
  issuerNameHash:    5e:b2:b4:42:e1:a5:..:b2:c3:9a:38:4f:cd (ok)
  serialNumber:      29:ff:36:d9:9a:21:49:61:91:1d
  thisUpdate:        Oct 19 16:13:23 UTC 2023
  nextUpdate:        Oct 19 16:23:23 UTC 2023
  certValidation:    REVOKED
  revocationTime:    Sep 22 13:13:04 UTC 2023
  revocationReason:  superseded
issuer:             "C=CH, O=strongSwan Project, CN=strongSwan Issuing CA 1"
  issuerKeyHash:     5a:1b:ec:17:f0:6d:..:a2:c8:e7:6a:84:20 (ok)
  issuerNameHash:    df:1e:24:71:96:e6:..:b9:82:18:45:e7:09 (ok)
  serialNumber:      10:ff:45:9a:6d:ee:4c:ec:7c:97
  thisUpdate:        Oct 19 16:13:23 UTC 2023
  nextUpdate:        Oct 19 16:23:23 UTC 2023
  certValidation:    GOOD
there are multiple known issuers
self-signed signer: "C=CH, O=strongSwan Project, CN=strongSwan OCSP signer"
ocspResponseStatus:  successful

see the glow-up? instead of trusted signer: you now get self-signed signer: πŸ’œ pointing at CN=strongSwan OCSP signer. there are multiple known issuers is still chillin' in there, and the status is still successful. iconic.


πŸ’– SEE ALSO πŸ’–


and that's the whole page, bestie!! πŸŽ€βœ¨ this was PKI --OCSP(1) β€” the --OCSP one, you know the one πŸ’… β€” from version 6.0.7, dated 2023-10-29. go forth and --respond responsibly, ily 🫢🌸

πŸ“¦ where this page comes from