Fix panic when PKCS7-encoded payload has no certificate
Some customers (ZenDesk: https://gitlab.zendesk.com/agent/tickets/191894) have certificate issuers that point to the US Federal Government CA via https://fpki.idmanagement.gov/crls/. Prior to this merge request, jobs that attempted to resolve the issuer certificate for this CA would fail:
Checking for jobs... received job=968529 repo_url=https://gitlab.example.com/group/project.git runner=26c23a42
Processing chain chain-leaf=[0xc0009fd080] context=certificate-chain-build
<snip>
Appending the certificate to the chain Issuer= IssuerCertURL=[http://pki.treasury.gov/noca_aia.p7c] Serial=1312391446 Subject= context=certificate-chain-build method=fetchIssuerCertificate newCertIssuer= newCertIssuerCertURL=[http://pki.treasury.gov/cacertsissuedtotrca.p7c] newCertSerial=1460481024 newCertSubject=
Checking for jobs... nothing runner=Jhy85A8N
Appending the certificate to the chain Issuer= IssuerCertURL=[http://pki.treasury.gov/cacertsissuedtotrca.p7c] Serial=1460481024 Subject= context=certificate-chain-build method=fetchIssuerCertificate newCertIssuer=Federal Common Policy CA newCertIssuerCertURL=[http://http.fpki.gov/fcpca/caCertsIssuedTofcpca.p7c] newCertSerial=29515 newCertSubject=
panic: runtime error: index out of range [0] with length 0
goroutine 194 [running]:
gitlab.com/gitlab-org/gitlab-runner/helpers/tls/ca_chain.decodeCertificate(0xc0007a6000, 0x29, 0x200, 0xc0007a6000, 0x29, 0x200)
/builds/gitlab-org/security/gitlab-runner/helpers/tls/ca_chain/helpers.go:66 +0x2be
This was happening because while the issuer certificate, as shown in newCertIssuerCertURL=[http://http.fpki.gov/fcpca/caCertsIssuedTofcpca.p7c]
, has a valid PKCS7 payload, it is empty:
$ curl -O http://http.fpki.gov/fcpca/caCertsIssuedTofcpca.p7c
$ openssl pkcs7 -print_certs -in caCertsIssuedTofcpca.p7c -inform DER -noout -print
PKCS7:
type: pkcs7-signedData (1.2.840.113549.1.7.2)
d.sign:
version: 1
md_algs:
<EMPTY>
contents:
type: pkcs7-data (1.2.840.113549.1.7.1)
d.data: <ABSENT>
cert:
<EMPTY>
crl:
<EMPTY>
signer_info:
<EMPTY>
pkcs7.Parse()
can return a nil payload if no certs were decoded: https://github.com/fullsailor/pkcs7/blob/d7302db945fa6ea264fb79d8e13e931ea514a602/pkcs7.go#L187
Instead of throwing up an error or crashing due to a nil access error, we ignore this issuer certificate and stop resolving credentials. If this root cert is trusted by the system, jobs will go through.