Source file src/crypto/x509/parser_fips140v1.0_test.go

     1  // Copyright 2026 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build fips140v1.0
     6  
     7  package x509
     8  
     9  import "testing"
    10  
    11  // TestParseMLDSACertificateFIPS140v1_0 verifies that ML-DSA certificates can
    12  // still be parsed under the FIPS 140-3 module v1.0.0, which doesn't support
    13  // ML-DSA. The parsed certificate has PublicKeyAlgorithm set to
    14  // UnknownPublicKeyAlgorithm and a nil PublicKey, so callers can inspect the
    15  // rest of the certificate without erroring.
    16  func TestParseMLDSACertificateFIPS140v1_0(t *testing.T) {
    17  	for _, tt := range []struct {
    18  		name string
    19  		pem  string
    20  	}{
    21  		{"ML-DSA-44", rfc9881ExampleCertificateMLDSA44},
    22  		{"ML-DSA-65", rfc9881ExampleCertificateMLDSA65},
    23  		{"ML-DSA-87", rfc9881ExampleCertificateMLDSA87},
    24  	} {
    25  		t.Run(tt.name, func(t *testing.T) {
    26  			cert, err := ParseCertificate(pemDecode(t, tt.pem))
    27  			if err != nil {
    28  				t.Fatalf("ParseCertificate failed: %v", err)
    29  			}
    30  			if cert.PublicKeyAlgorithm != UnknownPublicKeyAlgorithm {
    31  				t.Errorf("PublicKeyAlgorithm = %v, want UnknownPublicKeyAlgorithm", cert.PublicKeyAlgorithm)
    32  			}
    33  			if cert.PublicKey != nil {
    34  				t.Errorf("PublicKey = %v, want nil", cert.PublicKey)
    35  			}
    36  			// The rest of the certificate should still be inspectable.
    37  			if cert.Subject.CommonName == "" {
    38  				t.Error("Subject.CommonName is empty; expected the certificate to be parsed")
    39  			}
    40  		})
    41  	}
    42  }
    43  
    44  // TestMLDSAUnavailableErrorsNotPanics asserts that the public x509 entry
    45  // points return errors (rather than panicking) when ML-DSA is unavailable.
    46  // The mldsa package documents that "methods are unreachable" on v1.0.0; this
    47  // test ensures x509 callers stay on the error path.
    48  func TestMLDSAUnavailableErrorsNotPanics(t *testing.T) {
    49  	// ParsePKIXPublicKey: extracts the raw SPKI from a parsed cert and parses
    50  	// the public key directly. Should return an error, not panic.
    51  	cert, err := ParseCertificate(pemDecode(t, rfc9881ExampleCertificateMLDSA44))
    52  	if err != nil {
    53  		t.Fatalf("ParseCertificate failed: %v", err)
    54  	}
    55  	if _, err := ParsePKIXPublicKey(cert.RawSubjectPublicKeyInfo); err == nil {
    56  		t.Error("ParsePKIXPublicKey: expected error, got nil")
    57  	}
    58  	// ParsePKCS8PrivateKey: ML-DSA seed-only private keys.
    59  	for _, tt := range []struct {
    60  		name string
    61  		pem  string
    62  	}{
    63  		{"ML-DSA-44", rfc9881ExamplePrivateKeyMLDSA44},
    64  		{"ML-DSA-65", rfc9881ExamplePrivateKeyMLDSA65},
    65  		{"ML-DSA-87", rfc9881ExamplePrivateKeyMLDSA87},
    66  	} {
    67  		t.Run(tt.name, func(t *testing.T) {
    68  			if _, err := ParsePKCS8PrivateKey(pemDecode(t, tt.pem)); err == nil {
    69  				t.Error("ParsePKCS8PrivateKey: expected error, got nil")
    70  			}
    71  		})
    72  	}
    73  }
    74  

View as plain text