Skip to content

Commit d84ec2c

Browse files
authored
Merge pull request #81 from alexandrebrg/feat_yk_2025_certs
Use yubico 2025 Root CA
2 parents bd925ae + 98ba7a2 commit d84ec2c

File tree

2 files changed

+305
-6
lines changed

2 files changed

+305
-6
lines changed

pkg/pgp/verify.go

Lines changed: 153 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ func (v *verifier) verify(req VerificationRequest) (*Attestation, error) {
7272

7373
root := v.Root
7474
if root == nil {
75+
// Try verifying with the old root CA first
7576
ca, err := yubicoCA()
7677
if err != nil {
7778
errs = append(errs, fmt.Errorf("parsing YubiCo Root CA: %v", err))
@@ -82,9 +83,24 @@ func (v *verifier) verify(req VerificationRequest) (*Attestation, error) {
8283

8384
// Verify signatures:
8485
// The Attestation Signer Cert from the yubikey must be signed by YubiCo's attestation root
85-
if err := verifySignature(root, req.AttestSignerCert); err != nil {
86-
errs = append(errs, fmt.Errorf("attestation signer certificate is not signed by the YubiCo OpenPGP Root CA: %v", err))
86+
// Try old root first, then new root with intermediates
87+
err := verifySignature(root, req.AttestSignerCert)
88+
if err == nil {
89+
// Old chain verification succeeded
90+
goto verifyCert
8791
}
92+
93+
// If old root fails, try the new certificate chain:
94+
// Root -> Attestation Intermediate B 1 -> OPGP Attestation B 1 -> Device Signer
95+
if err := v.tryNewCertChain(req.AttestSignerCert); err == nil {
96+
// New chain verification succeeded
97+
goto verifyCert
98+
}
99+
100+
// Both chains failed
101+
errs = append(errs, fmt.Errorf("attestation signer certificate is not signed by the YubiCo OpenPGP Root CA: %v", err))
102+
103+
verifyCert:
88104
// The Attestation Cert must be signed by the Attestation Signer Cert
89105
if err := verifySignature(req.AttestSignerCert, req.AttestCert); err != nil {
90106
errs = append(errs, fmt.Errorf("attestation certificate not signed by device's attestation signer key: %v", err))
@@ -161,7 +177,41 @@ func verifySignature(parent, c *x509.Certificate) error {
161177
return parent.CheckSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature)
162178
}
163179

164-
// yubicoPGPCAPEM is the PEM encoded attestation certificate used by Yubico for OpenPGP keys.
180+
// tryNewCertChain attempts to verify the attestation signer cert using the new (2024+) certificate chain.
181+
// Returns nil if verification succeeds, error otherwise.
182+
func (v *verifier) tryNewCertChain(signerCert *x509.Certificate) error {
183+
// Load all certificates in the new chain
184+
newRoot, err := yubicoNewRootCA()
185+
if err != nil {
186+
return err
187+
}
188+
189+
attestInt, err := yubicoAttestationIntermediateB()
190+
if err != nil {
191+
return err
192+
}
193+
194+
opgpInt, err := yubicoOPGPIntermediate()
195+
if err != nil {
196+
return err
197+
}
198+
199+
// Verify: new root -> attestation intermediate B
200+
if err := verifySignature(newRoot, attestInt); err != nil {
201+
return err
202+
}
203+
204+
// Verify: attestation intermediate B -> OPGP intermediate
205+
if err := verifySignature(attestInt, opgpInt); err != nil {
206+
return err
207+
}
208+
209+
// Verify: OPGP intermediate -> attestation signer cert
210+
return verifySignature(opgpInt, signerCert)
211+
}
212+
213+
// yubicoPGPCAPEM is the legacy PEM encoded attestation certificate used by Yubico for OpenPGP keys.
214+
// This is the original root CA used by older YubiKeys (pre-2024).
165215
//
166216
// https://developers.yubico.com/PGP/Attestation.html
167217
// https://github.com/Yubico/developers.yubico.com/blob/master/content/PGP/Attestation.adoc
@@ -187,10 +237,110 @@ HhK6CLTg2MfwT0NxS3Am76k2opXSqbk8k5nnNFSYFuvgxunQxUOB+3M+gWHmVTh8
187237
7yaamyNndwmhhIAgeA==
188238
-----END CERTIFICATE-----`
189239

240+
// yubicoNewRootCAPEM is the new Yubico Attestation Root 1 issued on 2024-12-01.
241+
// Newer YubiKeys (2024+) use a new certificate chain with this root.
242+
//
243+
// https://developers.yubico.com/PKI/yubico-ca-1.pem
244+
const yubicoNewRootCAPEM = `-----BEGIN CERTIFICATE-----
245+
MIIDPjCCAiagAwIBAgIUXzeiEDJEOTt14F5n0o6Zf/bBwiUwDQYJKoZIhvcNAQEN
246+
BQAwJDEiMCAGA1UEAwwZWXViaWNvIEF0dGVzdGF0aW9uIFJvb3QgMTAgFw0yNDEy
247+
MDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowJDEiMCAGA1UEAwwZWXViaWNvIEF0
248+
dGVzdGF0aW9uIFJvb3QgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
249+
AMZ6/TxM8rIT+EaoPvG81ontMOo/2mQ2RBwJHS0QZcxVaNXvl12LUhBZ5LmiBScI
250+
Zd1Rnx1od585h+/dhK7hEm7JAALkKKts1fO53KGNLZujz5h3wGncr4hyKF0G74b/
251+
U3K9hE5mGND6zqYchCRAHfrYMYRDF4YL0X4D5nGdxvppAy6nkEmtWmMnwO3i0TAu
252+
csrbE485HvGM4r0VpgVdJpvgQjiTJCTIq+D35hwtT8QDIv+nGvpcyi5wcIfCkzyC
253+
imJukhYy6KoqNMKQEdpNiSOvWyDMTMt1bwCvEzpw91u+msUt4rj0efnO9s0ZOwdw
254+
MRDnH4xgUl5ZLwrrPkfC1/0CAwEAAaNmMGQwHQYDVR0OBBYEFNLu71oijTptXCOX
255+
PfKF1SbxJXuSMB8GA1UdIwQYMBaAFNLu71oijTptXCOXPfKF1SbxJXuSMBIGA1Ud
256+
EwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBDQUAA4IB
257+
AQC3IW/sgB9pZ8apJNjxuGoX+FkILks0wMNrdXL/coUvsrhzsvl6mePMrbGJByJ1
258+
XnquB5sgcRENFxdQFma3mio8Upf1owM1ZreXrJ0mADG2BplqbJnxiyYa+R11reIF
259+
TWeIhMNcZKsDZrFAyPuFjCWSQvJmNWe9mFRYFgNhXJKkXIb5H1XgEDlwiedYRM7V
260+
olBNlld6pRFKlX8ust6OTMOeADl2xNF0m1LThSdeuXvDyC1g9+ILfz3S6OIYgc3i
261+
roRcFD354g7rKfu67qFAw9gC4yi0xBTPrY95rh4/HqaUYCA/L8ldRk6H7Xk35D+W
262+
Vpmq2Sh/xT5HiFuhf4wJb0bK
263+
-----END CERTIFICATE-----`
264+
265+
// yubicoAttestationIntermediateBPEM is the middle intermediate in the new cert chain.
266+
// Chain: Root -> Attestation Intermediate B 1 -> OPGP Attestation B 1 -> Device Signer
267+
//
268+
// https://developers.yubico.com/PKI/yubico-intermediate.pem
269+
const yubicoAttestationIntermediateBPEM = `-----BEGIN CERTIFICATE-----
270+
MIIDSDCCAjCgAwIBAgIUDqERw+4RnGSggxgUewJFEPDRZ3YwDQYJKoZIhvcNAQEL
271+
BQAwJDEiMCAGA1UEAwwZWXViaWNvIEF0dGVzdGF0aW9uIFJvb3QgMTAgFw0yNDEy
272+
MDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowLjEsMCoGA1UEAwwjWXViaWNvIEF0
273+
dGVzdGF0aW9uIEludGVybWVkaWF0ZSBCIDEwggEiMA0GCSqGSIb3DQEBAQUAA4IB
274+
DwAwggEKAoIBAQDI7XnH+ZvDwMCQU8M8ZeV5qscublvVYaaRt3Ybaxn9godLx5sw
275+
H0lXrdgjh5h7FpVgCgYYX7E4bl1vbzULemrMWT8N3WMGUe8QAJbBeioV7W/E+hTZ
276+
P/0SKJVa3ewKBo6ULeMnfQZDrVORAk8wTLq2v5Llj5vMj7JtOotKa9J7nHS8kLmz
277+
XXSaj0SwEPh5OAZUTNV4zs1bvoTAQQWrL4/J9QuKt6WCFE5nUNiRQcEbVF8mlqK2
278+
bx2z6okVltyDVLCxYbpUTELvY1usR3DTGPUoIClOm4crpwnDRLVHvjYePGBB//pE
279+
yzxA/gcScxjwaH1ZUw9bnSbHyurKqbTa1KvjAgMBAAGjZjBkMB0GA1UdDgQWBBTq
280+
t0KQngx7ZHrbVHwDunxOn9ihYTAfBgNVHSMEGDAWgBTS7u9aIo06bVwjlz3yhdUm
281+
8SV7kjASBgNVHRMBAf8ECDAGAQH/AgECMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
282+
9w0BAQsFAAOCAQEAqQaCWMxTGqVVX7Sk7kkJmUueTSYKuU6+KBBSgwIRnlw9K7He
283+
1IpxZ0hdwpPNikKjmcyFgFPzhImwHJgxxuT90Pw3vYOdcJJNktDg35PXOfzSn15c
284+
FAx1RO0mPTmIb8dXiEWOpzoXvdwXDM41ZaCDYMT7w4IQtMyvE7xUBZq2bjtAnq/N
285+
DUA7be4H8H3ipC+/+NKlUrcUh+j48K67WI0u1m6FeQueBA7n06j825rqDqsaLs9T
286+
b7KAHAw8PmrWaNPG2kjKerxPEfecivlFawp2RWZvxrVtn3TV2SBxyCJCkXsND05d
287+
CErVHSJIs+BdtTVNY9AwtyPmnyb0v4mSTzvWdw==
288+
-----END CERTIFICATE-----`
289+
290+
// yubicoOPGPIntermediatePEM contains the intermediate certificate used in the new cert chain.
291+
// This intermediate is signed by Yubico Attestation Intermediate B 1 which is signed by
292+
// Yubico Attestation Root 1, and signs the device attestation signers.
293+
//
294+
// https://developers.yubico.com/PKI/yubico-intermediate.pem
295+
const yubicoOPGPIntermediatePEM = `-----BEGIN CERTIFICATE-----
296+
MIIDSjCCAjKgAwIBAgIUbeEhxjsv7XjQwdAQIi5G5i+4qhIwDQYJKoZIhvcNAQEL
297+
BQAwLjEsMCoGA1UEAwwjWXViaWNvIEF0dGVzdGF0aW9uIEludGVybWVkaWF0ZSBC
298+
IDEwIBcNMjQxMjAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMCYxJDAiBgNVBAMM
299+
G1l1YmljbyBPUEdQIEF0dGVzdGF0aW9uIEIgMTCCASIwDQYJKoZIhvcNAQEBBQAD
300+
ggEPADCCAQoCggEBAMe9oJ6kuLQOlnUoyWzDaum4m23s3cR5jn0gVQSV6VPsQP8Q
301+
d7wYiW/GiDUPAT4N/NqKdhcqX/5hazrbsKA+gCDU1E+zWunl0J0Fo5B0OCXQfxtA
302+
0LhFHORvpJ1yz7HsRgEYScO7/rO2ip0bPbaKy4MG4UhyzKgzwmujOO7nmf6BcMil
303+
8ZZRJbQOuEWsignM5EKuCrymyK3+R9Y+8NGjh/zb14Not9+JvwDgUYnHW+hip9si
304+
UOzC2X8QYA/yBUCqTYGUePfC4ZOB0ZSi/HYtxhSnOTcDY6C+AcFnOCvCKD8t4Rdd
305+
z6dFJINQgsATnfHycB22cUamIB9hBb9xXZYg36sCAwEAAaNmMGQwHQYDVR0OBBYE
306+
FI1QCVLy1KcdxIkdZMMkn+wzyN0XMB8GA1UdIwQYMBaAFOq3QpCeDHtkettUfAO6
307+
fE6f2KFhMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqG
308+
SIb3DQEBCwUAA4IBAQCRtalpNipOThRLO8o0/4WVLIjlC8yiPBLsVMuXHuXhTdhW
309+
ubRUSazhHr7tTRShPJ/OeWiiap9aZtZe7FUgTIOdaR0oI4Tp5Cu4TUJTLQEUqtA9
310+
HSU6bP485aRJi26hDD+h2AYplmEeVNEWj8PUIAp3N8mKMMqIkjB7d0QN14fze/Nb
311+
REzHU6SVvuJo11jfHpJTfpbpCqvcVl8bMPUbdtOvqc1ibkj7O7OmTDACqTT1f3yQ
312+
Zj0PbreP1qN9jv7kDAxT9O2yVSgXNXbz/Ygl121TkGWjXRQ8B3PW2Z3+n7B8ETAd
313+
8fJ0/5guPgvO2VQHQv8H9U3tsqSq/siosMJ8KtS5
314+
-----END CERTIFICATE-----`
315+
190316
func yubicoCA() (*x509.Certificate, error) {
191317
b, _ := pem.Decode([]byte(yubicoPGPCAPEM))
192318
if b == nil {
193319
return nil, fmt.Errorf("failed to decode yubico pem data")
194320
}
195321
return x509.ParseCertificate(b.Bytes)
196322
}
323+
324+
func yubicoNewRootCA() (*x509.Certificate, error) {
325+
b, _ := pem.Decode([]byte(yubicoNewRootCAPEM))
326+
if b == nil {
327+
return nil, fmt.Errorf("failed to decode new yubico root CA pem data")
328+
}
329+
return x509.ParseCertificate(b.Bytes)
330+
}
331+
332+
func yubicoAttestationIntermediateB() (*x509.Certificate, error) {
333+
b, _ := pem.Decode([]byte(yubicoAttestationIntermediateBPEM))
334+
if b == nil {
335+
return nil, fmt.Errorf("failed to decode yubico attestation intermediate B pem data")
336+
}
337+
return x509.ParseCertificate(b.Bytes)
338+
}
339+
340+
func yubicoOPGPIntermediate() (*x509.Certificate, error) {
341+
b, _ := pem.Decode([]byte(yubicoOPGPIntermediatePEM))
342+
if b == nil {
343+
return nil, fmt.Errorf("failed to decode yubico OPGP intermediate pem data")
344+
}
345+
return x509.ParseCertificate(b.Bytes)
346+
}

pkg/piv/verify.go

Lines changed: 152 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,24 @@ func (v *verifier) verify(req VerificationRequest) (*Attestation, error) {
101101

102102
// Verify signatures:
103103
// The Attestation Signer Cert from the yubikey must be signed by YubiCo's attestation root
104-
if err := verifySignature(root, req.AttestSignerCert); err != nil {
105-
errs = append(errs, fmt.Errorf("attestation signer certificate is not signed by YubiCo PIV Root CA: %v", err))
104+
// Try old root first, then new root with intermediates
105+
err := verifySignature(root, req.AttestSignerCert)
106+
if err == nil {
107+
// Old chain verification succeeded
108+
goto verifyCert
106109
}
110+
111+
// If old root fails, try the new certificate chain:
112+
// Root -> Attestation Intermediate B 1 -> PIV Attestation B 1 -> Device Signer
113+
if err := v.tryNewCertChain(req.AttestSignerCert); err == nil {
114+
// New chain verification succeeded
115+
goto verifyCert
116+
}
117+
118+
// Both chains failed
119+
errs = append(errs, fmt.Errorf("attestation signer certificate is not signed by YubiCo PIV Root CA: %v", err))
120+
121+
verifyCert:
107122
// The Attestation Cert must be signed by the Attestation Signer Cert
108123
if err := verifySignature(req.AttestSignerCert, req.AttestCert); err != nil {
109124
errs = append(errs, fmt.Errorf("attestation certificate not signed by device's attestation signer key: %v", err))
@@ -167,7 +182,41 @@ func verifySignature(parent, c *x509.Certificate) error {
167182
return parent.CheckSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature)
168183
}
169184

170-
// yubicoPIVCAPEM is the PEM encoded attestation certificate used by Yubico for PIV keys.
185+
// tryNewCertChain attempts to verify the attestation signer cert using the new (2024+) certificate chain.
186+
// Returns nil if verification succeeds, error otherwise.
187+
func (v *verifier) tryNewCertChain(signerCert *x509.Certificate) error {
188+
// Load all certificates in the new chain
189+
newRoot, err := yubicoNewRootCA()
190+
if err != nil {
191+
return err
192+
}
193+
194+
attestInt, err := yubicoAttestationIntermediateB()
195+
if err != nil {
196+
return err
197+
}
198+
199+
pivInt, err := yubicoPIVIntermediate()
200+
if err != nil {
201+
return err
202+
}
203+
204+
// Verify: new root -> attestation intermediate B
205+
if err := verifySignature(newRoot, attestInt); err != nil {
206+
return err
207+
}
208+
209+
// Verify: attestation intermediate B -> PIV intermediate
210+
if err := verifySignature(attestInt, pivInt); err != nil {
211+
return err
212+
}
213+
214+
// Verify: PIV intermediate -> attestation signer cert
215+
return verifySignature(pivInt, signerCert)
216+
}
217+
218+
// yubicoPIVCAPEM is the legacy PEM encoded attestation certificate used by Yubico for PIV keys.
219+
// This is the original root CA used by older YubiKeys (pre-2024).
171220
//
172221
// https://developers.yubico.com/PIV/Introduction/PIV_attestation.html
173222
// https://developers.yubico.com/PIV/Introduction/piv-attestation-ca.pem
@@ -191,10 +240,110 @@ Fqyi4+JE014cSgR57Jcu3dZiehB6UtAPgad9L5cNvua/IWRmm+ANy3O2LH++Pyl8
191240
SREzU8onbBsjMg9QDiSf5oJLKvd/Ren+zGY7
192241
-----END CERTIFICATE-----`
193242

243+
// yubicoNewRootCAPEM is the new Yubico Attestation Root 1 issued on 2024-12-01.
244+
// Newer YubiKeys (2024+) use a new certificate chain with this root.
245+
//
246+
// https://developers.yubico.com/PKI/yubico-ca-1.pem
247+
const yubicoNewRootCAPEM = `-----BEGIN CERTIFICATE-----
248+
MIIDPjCCAiagAwIBAgIUXzeiEDJEOTt14F5n0o6Zf/bBwiUwDQYJKoZIhvcNAQEN
249+
BQAwJDEiMCAGA1UEAwwZWXViaWNvIEF0dGVzdGF0aW9uIFJvb3QgMTAgFw0yNDEy
250+
MDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowJDEiMCAGA1UEAwwZWXViaWNvIEF0
251+
dGVzdGF0aW9uIFJvb3QgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
252+
AMZ6/TxM8rIT+EaoPvG81ontMOo/2mQ2RBwJHS0QZcxVaNXvl12LUhBZ5LmiBScI
253+
Zd1Rnx1od585h+/dhK7hEm7JAALkKKts1fO53KGNLZujz5h3wGncr4hyKF0G74b/
254+
U3K9hE5mGND6zqYchCRAHfrYMYRDF4YL0X4D5nGdxvppAy6nkEmtWmMnwO3i0TAu
255+
csrbE485HvGM4r0VpgVdJpvgQjiTJCTIq+D35hwtT8QDIv+nGvpcyi5wcIfCkzyC
256+
imJukhYy6KoqNMKQEdpNiSOvWyDMTMt1bwCvEzpw91u+msUt4rj0efnO9s0ZOwdw
257+
MRDnH4xgUl5ZLwrrPkfC1/0CAwEAAaNmMGQwHQYDVR0OBBYEFNLu71oijTptXCOX
258+
PfKF1SbxJXuSMB8GA1UdIwQYMBaAFNLu71oijTptXCOXPfKF1SbxJXuSMBIGA1Ud
259+
EwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBDQUAA4IB
260+
AQC3IW/sgB9pZ8apJNjxuGoX+FkILks0wMNrdXL/coUvsrhzsvl6mePMrbGJByJ1
261+
XnquB5sgcRENFxdQFma3mio8Upf1owM1ZreXrJ0mADG2BplqbJnxiyYa+R11reIF
262+
TWeIhMNcZKsDZrFAyPuFjCWSQvJmNWe9mFRYFgNhXJKkXIb5H1XgEDlwiedYRM7V
263+
olBNlld6pRFKlX8ust6OTMOeADl2xNF0m1LThSdeuXvDyC1g9+ILfz3S6OIYgc3i
264+
roRcFD354g7rKfu67qFAw9gC4yi0xBTPrY95rh4/HqaUYCA/L8ldRk6H7Xk35D+W
265+
Vpmq2Sh/xT5HiFuhf4wJb0bK
266+
-----END CERTIFICATE-----`
267+
268+
// yubicoAttestationIntermediateBPEM is the middle intermediate in the new cert chain.
269+
// Chain: Root -> Attestation Intermediate B 1 -> PIV Attestation B 1 -> Device Signer
270+
//
271+
// https://developers.yubico.com/PKI/yubico-intermediate.pem
272+
const yubicoAttestationIntermediateBPEM = `-----BEGIN CERTIFICATE-----
273+
MIIDSDCCAjCgAwIBAgIUDqERw+4RnGSggxgUewJFEPDRZ3YwDQYJKoZIhvcNAQEL
274+
BQAwJDEiMCAGA1UEAwwZWXViaWNvIEF0dGVzdGF0aW9uIFJvb3QgMTAgFw0yNDEy
275+
MDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowLjEsMCoGA1UEAwwjWXViaWNvIEF0
276+
dGVzdGF0aW9uIEludGVybWVkaWF0ZSBCIDEwggEiMA0GCSqGSIb3DQEBAQUAA4IB
277+
DwAwggEKAoIBAQDI7XnH+ZvDwMCQU8M8ZeV5qscublvVYaaRt3Ybaxn9godLx5sw
278+
H0lXrdgjh5h7FpVgCgYYX7E4bl1vbzULemrMWT8N3WMGUe8QAJbBeioV7W/E+hTZ
279+
P/0SKJVa3ewKBo6ULeMnfQZDrVORAk8wTLq2v5Llj5vMj7JtOotKa9J7nHS8kLmz
280+
XXSaj0SwEPh5OAZUTNV4zs1bvoTAQQWrL4/J9QuKt6WCFE5nUNiRQcEbVF8mlqK2
281+
bx2z6okVltyDVLCxYbpUTELvY1usR3DTGPUoIClOm4crpwnDRLVHvjYePGBB//pE
282+
yzxA/gcScxjwaH1ZUw9bnSbHyurKqbTa1KvjAgMBAAGjZjBkMB0GA1UdDgQWBBTq
283+
t0KQngx7ZHrbVHwDunxOn9ihYTAfBgNVHSMEGDAWgBTS7u9aIo06bVwjlz3yhdUm
284+
8SV7kjASBgNVHRMBAf8ECDAGAQH/AgECMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
285+
9w0BAQsFAAOCAQEAqQaCWMxTGqVVX7Sk7kkJmUueTSYKuU6+KBBSgwIRnlw9K7He
286+
1IpxZ0hdwpPNikKjmcyFgFPzhImwHJgxxuT90Pw3vYOdcJJNktDg35PXOfzSn15c
287+
FAx1RO0mPTmIb8dXiEWOpzoXvdwXDM41ZaCDYMT7w4IQtMyvE7xUBZq2bjtAnq/N
288+
DUA7be4H8H3ipC+/+NKlUrcUh+j48K67WI0u1m6FeQueBA7n06j825rqDqsaLs9T
289+
b7KAHAw8PmrWaNPG2kjKerxPEfecivlFawp2RWZvxrVtn3TV2SBxyCJCkXsND05d
290+
CErVHSJIs+BdtTVNY9AwtyPmnyb0v4mSTzvWdw==
291+
-----END CERTIFICATE-----`
292+
293+
// yubicoPIVIntermediatePEM contains the PIV intermediate certificate used in the new cert chain.
294+
// This intermediate is signed by Yubico Attestation Intermediate B 1 which is signed by
295+
// Yubico Attestation Root 1, and signs the device attestation signers.
296+
//
297+
// https://developers.yubico.com/PKI/yubico-intermediate.pem
298+
const yubicoPIVIntermediatePEM = `-----BEGIN CERTIFICATE-----
299+
MIIDSTCCAjGgAwIBAgIUWVf2oJG+t1qP8t8TicWgJ2KYan4wDQYJKoZIhvcNAQEL
300+
BQAwLjEsMCoGA1UEAwwjWXViaWNvIEF0dGVzdGF0aW9uIEludGVybWVkaWF0ZSBC
301+
IDEwIBcNMjQxMjAxMDAwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMCUxIzAhBgNVBAMM
302+
Gll1YmljbyBQSVYgQXR0ZXN0YXRpb24gQiAxMIIBIjANBgkqhkiG9w0BAQEFAAOC
303+
AQ8AMIIBCgKCAQEAv7WBL9/5AKxSpCMoL63183WqRtFrOHY7tdyuGtoidoYWQrxV
304+
aV9S+ZwH0aynh0IzD5A/PvCtuxdtL5w2cAI3tgsborOlEert4IZ904CZQfq3ooar
305+
1an/wssbtMpPOQkC3MQiqrUyHlFS2BTbuwbBXY66lSVX/tGRuUgnBdfBJtcQKS6M
306+
O4bU5ndPQqhGPyzcyY1LvlfzK7KJ1r/bixCRFqjhJRnPs0Czpg6rkRrFgC6cd5bK
307+
1UgTsJy+3wrIqkv4CeV3EhSVnhnQjZgIrdIcI5WZ8T1Oq3OhMlWmY0K0dy/oZdP/
308+
bpbG2qbyHLa6gprLT/qChQWLmffxn6D2DAB1zQIDAQABo2YwZDAdBgNVHQ4EFgQU
309+
M0Nt3QHo7eGzaKMZn2SmXT74vpcwHwYDVR0jBBgwFoAU6rdCkJ4Me2R621R8A7p8
310+
Tp/YoWEwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZI
311+
hvcNAQELBQADggEBAI0HwoS84fKMUyIof1LdUXvyeAMmEwW7+nVETvxNNlTMuwv7
312+
zPJ4XZAm9Fv95tz9CqZBj6l1PAPQn6Zht9LQA92OF7W7buuXuxuusBTgLM0C1iX2
313+
CGXqY/k/uSNvi3ZYfrpd44TIrfrr8bCG9ux7B5ZCRqb8adDUm92Yz3lK1aX2M6Cw
314+
jC9IZVTXQWhLyP8Ys3p7rb20CO2jJzV94deJ/+AsEb+bnCQImPat1GDKwrBosar+
315+
BxtU7k6kgkxZ0G384O59GFXqnwkbw2b5HhORvOsX7nhOUhePFufzi1vT1g8Tzbwr
316+
+TUfTwo2biKHHcI762KGtp8o6Bcv5y8WgExFuWY=
317+
-----END CERTIFICATE-----`
318+
194319
func yubicoCA() (*x509.Certificate, error) {
195320
b, _ := pem.Decode([]byte(yubicoPIVCAPEM))
196321
if b == nil {
197322
return nil, fmt.Errorf("failed to decode yubico pem data")
198323
}
199324
return x509.ParseCertificate(b.Bytes)
200325
}
326+
327+
func yubicoNewRootCA() (*x509.Certificate, error) {
328+
b, _ := pem.Decode([]byte(yubicoNewRootCAPEM))
329+
if b == nil {
330+
return nil, fmt.Errorf("failed to decode new yubico root CA pem data")
331+
}
332+
return x509.ParseCertificate(b.Bytes)
333+
}
334+
335+
func yubicoAttestationIntermediateB() (*x509.Certificate, error) {
336+
b, _ := pem.Decode([]byte(yubicoAttestationIntermediateBPEM))
337+
if b == nil {
338+
return nil, fmt.Errorf("failed to decode yubico attestation intermediate B pem data")
339+
}
340+
return x509.ParseCertificate(b.Bytes)
341+
}
342+
343+
func yubicoPIVIntermediate() (*x509.Certificate, error) {
344+
b, _ := pem.Decode([]byte(yubicoPIVIntermediatePEM))
345+
if b == nil {
346+
return nil, fmt.Errorf("failed to decode yubico PIV intermediate pem data")
347+
}
348+
return x509.ParseCertificate(b.Bytes)
349+
}

0 commit comments

Comments
 (0)