package capsule_test
import (
Tests of the CMS reader: certificates field by field, every check, fuzzing
The builder of the tests, cmstest:
- NewCert writes a certificate from the DER of its tbsCertificate, field by
field: names of any string type with any bytes (UTF8String,
PrintableString with an underscore or an at sign, IA5String,
TeletexString, BMPString of odd length or with a surrogate,
VisibleString, NumericString), an attribute twice or none, no version,
times with a fraction, an extension twice, a compressed EC key, an even
modulus, and any signature. A Signer made so serves Signature and Token.
- Options for the version of a SignerInfo, the hashAlgorithm and the
certHash of an ESSCertIDv2, a signatureAlgorithm other than the one of
the key, a certificate twice, two content-type attributes, an attribute
with an arc of 2^31, a SignerInfo twice, BER, signerInfos out of order,
two signature-time-stamp attributes, and edits of the SignedData and of
each SignerInfo.
- Token options for any accuracy, a genTime of free text, ordering FALSE,
a field after the last, an imprint of any length, no message-digest, a
CRL in crls and the certificate of the authority twice.
- Edits of the DER after signing: Edit, Retag, Withdraw (a SignerInfo
removed), WithoutTimeStamp (a CAdES-T removed), Merge (a co-signature)
and Indefinite.
The tests of internal/cms and internal/der fail for each check of cms.go,
cert.go, verify.go and der.go. A mutation run, which replaces each leaf of
each condition by false and by true, one at a time, kills every mutant
that is not equivalent to the code it mutates.
FuzzParseSignature, FuzzParseToken, FuzzParseCert and FuzzDERCheck, seeded
with security_cms.json and with what cmstest builds: no panic, what Check
accepts Split reads, and the parsers fail only with ErrForm or
ErrAlgorithm.
capsule: the case of a seal outside the validity of the certificate gave
an invalid seal; it now tests a certificate that expired before a valid
seal (out of validity) apart from an authority that was not valid at its
time (invalid seal). SIGNERS out of order, empty, too long, with 31 bytes
or with a hash twice are F1 beside a CMS signature that is valid for the
AUTHOR_MESSAGE of those SIGNERS, and the names of certificates show as
spec v0.12 §29.7 says.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
"bytes"
"crypto"
Tests of the CMS reader: certificates field by field, every check, fuzzing
The builder of the tests, cmstest:
- NewCert writes a certificate from the DER of its tbsCertificate, field by
field: names of any string type with any bytes (UTF8String,
PrintableString with an underscore or an at sign, IA5String,
TeletexString, BMPString of odd length or with a surrogate,
VisibleString, NumericString), an attribute twice or none, no version,
times with a fraction, an extension twice, a compressed EC key, an even
modulus, and any signature. A Signer made so serves Signature and Token.
- Options for the version of a SignerInfo, the hashAlgorithm and the
certHash of an ESSCertIDv2, a signatureAlgorithm other than the one of
the key, a certificate twice, two content-type attributes, an attribute
with an arc of 2^31, a SignerInfo twice, BER, signerInfos out of order,
two signature-time-stamp attributes, and edits of the SignedData and of
each SignerInfo.
- Token options for any accuracy, a genTime of free text, ordering FALSE,
a field after the last, an imprint of any length, no message-digest, a
CRL in crls and the certificate of the authority twice.
- Edits of the DER after signing: Edit, Retag, Withdraw (a SignerInfo
removed), WithoutTimeStamp (a CAdES-T removed), Merge (a co-signature)
and Indefinite.
The tests of internal/cms and internal/der fail for each check of cms.go,
cert.go, verify.go and der.go. A mutation run, which replaces each leaf of
each condition by false and by true, one at a time, kills every mutant
that is not equivalent to the code it mutates.
FuzzParseSignature, FuzzParseToken, FuzzParseCert and FuzzDERCheck, seeded
with security_cms.json and with what cmstest builds: no panic, what Check
accepts Split reads, and the parsers fail only with ErrForm or
ErrAlgorithm.
capsule: the case of a seal outside the validity of the certificate gave
an invalid seal; it now tests a certificate that expired before a valid
seal (out of validity) apart from an authority that was not valid at its
time (invalid seal). SIGNERS out of order, empty, too long, with 31 bytes
or with a hash twice are F1 beside a CMS signature that is valid for the
AUTHOR_MESSAGE of those SIGNERS, and the names of certificates show as
spec v0.12 §29.7 says.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
"crypto/ecdsa"
"crypto/elliptic"
"crypto/sha256"
Tests of the CMS reader: certificates field by field, every check, fuzzing
The builder of the tests, cmstest:
- NewCert writes a certificate from the DER of its tbsCertificate, field by
field: names of any string type with any bytes (UTF8String,
PrintableString with an underscore or an at sign, IA5String,
TeletexString, BMPString of odd length or with a surrogate,
VisibleString, NumericString), an attribute twice or none, no version,
times with a fraction, an extension twice, a compressed EC key, an even
modulus, and any signature. A Signer made so serves Signature and Token.
- Options for the version of a SignerInfo, the hashAlgorithm and the
certHash of an ESSCertIDv2, a signatureAlgorithm other than the one of
the key, a certificate twice, two content-type attributes, an attribute
with an arc of 2^31, a SignerInfo twice, BER, signerInfos out of order,
two signature-time-stamp attributes, and edits of the SignedData and of
each SignerInfo.
- Token options for any accuracy, a genTime of free text, ordering FALSE,
a field after the last, an imprint of any length, no message-digest, a
CRL in crls and the certificate of the authority twice.
- Edits of the DER after signing: Edit, Retag, Withdraw (a SignerInfo
removed), WithoutTimeStamp (a CAdES-T removed), Merge (a co-signature)
and Indefinite.
The tests of internal/cms and internal/der fail for each check of cms.go,
cert.go, verify.go and der.go. A mutation run, which replaces each leaf of
each condition by false and by true, one at a time, kills every mutant
that is not equivalent to the code it mutates.
FuzzParseSignature, FuzzParseToken, FuzzParseCert and FuzzDERCheck, seeded
with security_cms.json and with what cmstest builds: no panic, what Check
accepts Split reads, and the parsers fail only with ErrForm or
ErrAlgorithm.
capsule: the case of a seal outside the validity of the certificate gave
an invalid seal; it now tests a certificate that expired before a valid
seal (out of validity) apart from an authority that was not valid at its
time (invalid seal). SIGNERS out of order, empty, too long, with 31 bytes
or with a hash twice are F1 beside a CMS signature that is valid for the
AUTHOR_MESSAGE of those SIGNERS, and the names of certificates show as
spec v0.12 §29.7 says.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
"encoding/hex"
Spec v0.12 draft and the verdicts of a certificate (not approved)
The draft v0.12 fixes what the review of the implementation of v0.11
found, without changing any format: the names of certificates in the
verdicts, the seal of each signer in the lines of F6 with the warning that
nobody checks who issued it, the holder by givenName and surname before
the commonName that carries the NIF, a profile of the certificate field by
field, identifiers by their bytes, repeated elements of a SET OF, the
edge cases of the token, the addresses and the padding of the locator, and
the errata of 44.1, 55.2, 64, 67 and 76. Section 76 lists each change with
its case. The CDDL fixes the sizes of the locator.
The reader shows the names of certificates between quotes, refuses one of
more than 64 code points or with two spaces in a row, names the authority
of each seal of F6 and adds the warning when a line says before the date,
and writes the result of a foreign signer in Spanish. The records of
format3_signed_cms and format3_sealed follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
"slices"
"strings"
"testing"
"time"
"g.activething.com/go/DateKeys/authorkey"
"g.activething.com/go/DateKeys/capsule"
"g.activething.com/go/DateKeys/internal/cms/cmstest"
)
var (
certFrom = time . Date ( 2025 , 1 , 1 , 0 , 0 , 0 , 0 , time . UTC )
certTo = time . Date ( 2032 , 1 , 1 , 0 , 0 , 0 , 0 , time . UTC )
roundTime = time . Date ( 2030 , 1 , 1 , 0 , 0 , 0 , 0 , time . UTC )
signedAt = time . Date ( 2026 , 9 , 30 , 12 , 0 , 0 , 0 , time . UTC )
)
func testContext ( ) * capsule . SecurityContext {
c := & capsule . SecurityContext { RoundTime : roundTime }
c . ControlCommit [ 0 ] , c . HeadDigest [ 0 ] = 1 , 2
return c
}
Spec v0.12 draft and the verdicts of a certificate (not approved)
The draft v0.12 fixes what the review of the implementation of v0.11
found, without changing any format: the names of certificates in the
verdicts, the seal of each signer in the lines of F6 with the warning that
nobody checks who issued it, the holder by givenName and surname before
the commonName that carries the NIF, a profile of the certificate field by
field, identifiers by their bytes, repeated elements of a SET OF, the
edge cases of the token, the addresses and the padding of the locator, and
the errata of 44.1, 55.2, 64, 67 and 76. Section 76 lists each change with
its case. The CDDL fixes the sizes of the locator.
The reader shows the names of certificates between quotes, refuses one of
more than 64 code points or with two spaces in a row, names the authority
of each seal of F6 and adds the warning when a line says before the date,
and writes the result of a foreign signer in Spanish. The records of
format3_signed_cms and format3_sealed follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
// quotedNames are the holders of the required signers of v as the text of F6
// writes them.
func quotedNames ( v capsule . Verdicts ) string {
var names [ ] string
for _ , s := range v . Detail . Signers {
names = append ( names , "«" + s . Holder + "»" )
}
return strings . Join ( names , ", " )
}
// cmsArea builds the SECURITY_CBOR of a capsule with an alg 2 signature by
// the signers, who all must sign, sealing each signature with tsa at when.
func cmsArea ( t * testing . T , c * capsule . SecurityContext , required [ ] cmstest . Signer , signers [ ] cmstest . Signer , tsa cmstest . Signer , when time . Time , seal [ ] byte ) [ ] byte {
t . Helper ( )
var hashes [ ] [ 32 ] byte
for _ , s := range required {
hashes = append ( hashes , sha256Sum ( s . Cert . Raw ) )
}
list , err := capsule . EncodeSigners ( hashes )
if err != nil {
t . Fatal ( err )
}
msg := capsule . AuthorMessage ( c . ControlCommit , c . HeadDigest , capsule . SignersDigest ( capsule . AlgCMS , list ) )
opts := cmstest . Options { }
if tsa . Key != nil {
opts . Token = func ( sig [ ] byte ) [ ] byte {
return cmstest . Token ( sig , when , cmstest . TokenOptions { Accuracy : time . Second } , tsa )
}
}
content , err := capsule . EncodeAuthorSignature ( capsule . AlgCMS , list , cmstest . Signature ( msg , opts , signers ... ) )
if err != nil {
t . Fatal ( err )
}
area , err := capsule . EncodeSecurityWith ( content , seal )
if err != nil {
t . Fatal ( err )
}
return area
}
// Spec v0.11 §29.7, §29.10: alg 2 gives F6 when every required signer is
// valid and sealed, and the first of F2, F5 and F1 that applies otherwise.
func TestEvaluateCMS ( t * testing . T ) {
ana := cmstest . NewECDSA ( "Ana López" , elliptic . P256 ( ) , certFrom , certTo )
luis := cmstest . NewRSA ( "Luis Gómez" , 2048 , certFrom , certTo )
otro := cmstest . NewECDSA ( "Otro" , elliptic . P384 ( ) , certFrom , certTo )
tsa := cmstest . NewECDSA ( "TSA de prueba" , elliptic . P256 ( ) , certFrom , certTo )
c := testContext ( )
// A co-signature, each with its seal: F6, with their names.
v := capsule . EvaluateSecurityIn ( cmsArea ( t , c , [ ] cmstest . Signer { ana , luis } , [ ] cmstest . Signer { ana , luis } , tsa , signedAt , nil ) , c )
if v . Signature != capsule . VerdictSignedComplete || v . Seal != capsule . VerdictNoSeal || v . Detail == nil || len ( v . Detail . Signers ) != 2 {
t . Fatalf ( "a complete co-signature: %+v" , v )
}
Spec v0.12 draft and the verdicts of a certificate (not approved)
The draft v0.12 fixes what the review of the implementation of v0.11
found, without changing any format: the names of certificates in the
verdicts, the seal of each signer in the lines of F6 with the warning that
nobody checks who issued it, the holder by givenName and surname before
the commonName that carries the NIF, a profile of the certificate field by
field, identifiers by their bytes, repeated elements of a SET OF, the
edge cases of the token, the addresses and the padding of the locator, and
the errata of 44.1, 55.2, 64, 67 and 76. Section 76 lists each change with
its case. The CDDL fixes the sizes of the locator.
The reader shows the names of certificates between quotes, refuses one of
more than 64 code points or with two spaces in a row, names the authority
of each seal of F6 and adds the warning when a line says before the date,
and writes the result of a foreign signer in Spanish. The records of
format3_signed_cms and format3_sealed follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
// The names between « and », the authority of each seal, and, since the
// lines say "before the date", that DateKeys does not check who issued the
// seals (spec §29.7).
lines := v . Lines ( )
Spec v0.12 draft and the verdicts of a certificate (not approved)
The draft v0.12 fixes what the review of the implementation of v0.11
found, without changing any format: the names of certificates in the
verdicts, the seal of each signer in the lines of F6 with the warning that
nobody checks who issued it, the holder by givenName and surname before
the commonName that carries the NIF, a profile of the certificate field by
field, identifiers by their bytes, repeated elements of a SET OF, the
edge cases of the token, the addresses and the padding of the locator, and
the errata of 44.1, 55.2, 64, 67 and 76. Section 76 lists each change with
its case. The CDDL fixes the sizes of the locator.
The reader shows the names of certificates between quotes, refuses one of
more than 64 code points or with two spaces in a row, names the authority
of each seal of F6 and adds the warning when a line says before the date,
and writes the result of a foreign signer in Spanish. The records of
format3_signed_cms and format3_sealed follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
at := signedAt . UTC ( ) . Format ( time . RFC3339Nano )
want := [ ] string {
"Firmado con un certificado a nombre de " + quotedNames ( v ) + ". DateKeys no comprueba quién lo emitió: para eso, exporta la firma a un validador oficial." ,
" «" + v . Detail . Signers [ 0 ] . Holder + "» (emisor según su certificado: «" + v . Detail . Signers [ 0 ] . Issuer + "»), sellado por «TSA de prueba» el " + at + ", antes de la fecha de apertura." ,
" «" + v . Detail . Signers [ 1 ] . Holder + "» (emisor según su certificado: «" + v . Detail . Signers [ 1 ] . Issuer + "»), sellado por «TSA de prueba» el " + at + ", antes de la fecha de apertura." ,
" DateKeys no comprueba quién emitió los sellos." ,
}
if ! slices . Equal ( lines , want ) || ! strings . Contains ( lines [ 0 ] , "«Ana López»" ) || ! strings . Contains ( lines [ 0 ] , "«Luis Gómez»" ) {
t . Errorf ( "lines %q, want %q" , lines , want )
}
Spec v0.12 draft and the verdicts of a certificate (not approved)
The draft v0.12 fixes what the review of the implementation of v0.11
found, without changing any format: the names of certificates in the
verdicts, the seal of each signer in the lines of F6 with the warning that
nobody checks who issued it, the holder by givenName and surname before
the commonName that carries the NIF, a profile of the certificate field by
field, identifiers by their bytes, repeated elements of a SET OF, the
edge cases of the token, the addresses and the padding of the locator, and
the errata of 44.1, 55.2, 64, 67 and 76. Section 76 lists each change with
its case. The CDDL fixes the sizes of the locator.
The reader shows the names of certificates between quotes, refuses one of
more than 64 code points or with two spaces in a row, names the authority
of each seal of F6 and adds the warning when a line says before the date,
and writes the result of a foreign signer in Spanish. The records of
format3_signed_cms and format3_sealed follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
// A seal after the round time proves nothing before it, and then no line
// warns of who issued it.
late := capsule . EvaluateSecurityIn ( cmsArea ( t , c , [ ] cmstest . Signer { ana } , [ ] cmstest . Signer { ana } , tsa , roundTime . Add ( time . Hour ) , nil ) , c )
Spec v0.12 draft and the verdicts of a certificate (not approved)
The draft v0.12 fixes what the review of the implementation of v0.11
found, without changing any format: the names of certificates in the
verdicts, the seal of each signer in the lines of F6 with the warning that
nobody checks who issued it, the holder by givenName and surname before
the commonName that carries the NIF, a profile of the certificate field by
field, identifiers by their bytes, repeated elements of a SET OF, the
edge cases of the token, the addresses and the padding of the locator, and
the errata of 44.1, 55.2, 64, 67 and 76. Section 76 lists each change with
its case. The CDDL fixes the sizes of the locator.
The reader shows the names of certificates between quotes, refuses one of
more than 64 code points or with two spaces in a row, names the authority
of each seal of F6 and adds the warning when a line says before the date,
and writes the result of a foreign signer in Spanish. The records of
format3_signed_cms and format3_sealed follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
if late . Signature != capsule . VerdictSignedComplete || len ( late . Lines ( ) ) != 2 || ! strings . Contains ( late . Lines ( ) [ 1 ] , "no antes de la fecha de apertura" ) {
t . Errorf ( "a late seal: %+v %q" , late , late . Lines ( ) )
}
Spec v0.12 draft and the verdicts of a certificate (not approved)
The draft v0.12 fixes what the review of the implementation of v0.11
found, without changing any format: the names of certificates in the
verdicts, the seal of each signer in the lines of F6 with the warning that
nobody checks who issued it, the holder by givenName and surname before
the commonName that carries the NIF, a profile of the certificate field by
field, identifiers by their bytes, repeated elements of a SET OF, the
edge cases of the token, the addresses and the padding of the locator, and
the errata of 44.1, 55.2, 64, 67 and 76. Section 76 lists each change with
its case. The CDDL fixes the sizes of the locator.
The reader shows the names of certificates between quotes, refuses one of
more than 64 code points or with two spaces in a row, names the authority
of each seal of F6 and adds the warning when a line says before the date,
and writes the result of a foreign signer in Spanish. The records of
format3_signed_cms and format3_sealed follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
// A signer who is not required shows apart, with its result in Spanish,
// and does not count.
f := capsule . EvaluateSecurityIn ( cmsArea ( t , c , [ ] cmstest . Signer { ana } , [ ] cmstest . Signer { ana , otro } , tsa , signedAt , nil ) , c )
Spec v0.12 draft and the verdicts of a certificate (not approved)
The draft v0.12 fixes what the review of the implementation of v0.11
found, without changing any format: the names of certificates in the
verdicts, the seal of each signer in the lines of F6 with the warning that
nobody checks who issued it, the holder by givenName and surname before
the commonName that carries the NIF, a profile of the certificate field by
field, identifiers by their bytes, repeated elements of a SET OF, the
edge cases of the token, the addresses and the padding of the locator, and
the errata of 44.1, 55.2, 64, 67 and 76. Section 76 lists each change with
its case. The CDDL fixes the sizes of the locator.
The reader shows the names of certificates between quotes, refuses one of
more than 64 code points or with two spaces in a row, names the authority
of each seal of F6 and adds the warning when a line says before the date,
and writes the result of a foreign signer in Spanish. The records of
format3_signed_cms and format3_sealed follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
if f . Signature != capsule . VerdictSignedComplete || len ( f . Detail . Foreign ) != 1 || f . Detail . Foreign [ 0 ] . Holder != "Otro" || f . Lines ( ) [ len ( f . Lines ( ) ) - 1 ] != " Otro firmante, «Otro»: válida. No cuenta." {
t . Errorf ( "a foreign signer: %+v %q" , f , f . Lines ( ) )
}
Tests of the CMS reader: certificates field by field, every check, fuzzing
The builder of the tests, cmstest:
- NewCert writes a certificate from the DER of its tbsCertificate, field by
field: names of any string type with any bytes (UTF8String,
PrintableString with an underscore or an at sign, IA5String,
TeletexString, BMPString of odd length or with a surrogate,
VisibleString, NumericString), an attribute twice or none, no version,
times with a fraction, an extension twice, a compressed EC key, an even
modulus, and any signature. A Signer made so serves Signature and Token.
- Options for the version of a SignerInfo, the hashAlgorithm and the
certHash of an ESSCertIDv2, a signatureAlgorithm other than the one of
the key, a certificate twice, two content-type attributes, an attribute
with an arc of 2^31, a SignerInfo twice, BER, signerInfos out of order,
two signature-time-stamp attributes, and edits of the SignedData and of
each SignerInfo.
- Token options for any accuracy, a genTime of free text, ordering FALSE,
a field after the last, an imprint of any length, no message-digest, a
CRL in crls and the certificate of the authority twice.
- Edits of the DER after signing: Edit, Retag, Withdraw (a SignerInfo
removed), WithoutTimeStamp (a CAdES-T removed), Merge (a co-signature)
and Indefinite.
The tests of internal/cms and internal/der fail for each check of cms.go,
cert.go, verify.go and der.go. A mutation run, which replaces each leaf of
each condition by false and by true, one at a time, kills every mutant
that is not equivalent to the code it mutates.
FuzzParseSignature, FuzzParseToken, FuzzParseCert and FuzzDERCheck, seeded
with security_cms.json and with what cmstest builds: no panic, what Check
accepts Split reads, and the parsers fail only with ErrForm or
ErrAlgorithm.
capsule: the case of a seal outside the validity of the certificate gave
an invalid seal; it now tests a certificate that expired before a valid
seal (out of validity) apart from an authority that was not valid at its
time (invalid seal). SIGNERS out of order, empty, too long, with 31 bytes
or with a hash twice are F1 beside a CMS signature that is valid for the
AUTHOR_MESSAGE of those SIGNERS, and the names of certificates show as
spec v0.12 §29.7 says.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
// F5, and the result of the first required signer (spec §29.10, steps 1
// to 7): the certificate of a signer that expired before the time of a
// valid seal is out of validity; a seal whose authority was not valid at
// its time is an invalid seal.
expired := cmstest . NewECDSA ( "Ana caducada" , elliptic . P256 ( ) , certFrom , signedAt . AddDate ( 0 , - 1 , 0 ) )
small := cmstest . NewRSA ( "Clave corta" , 1024 , certFrom , certTo )
for name , tc := range map [ string ] struct {
Tests of the CMS reader: certificates field by field, every check, fuzzing
The builder of the tests, cmstest:
- NewCert writes a certificate from the DER of its tbsCertificate, field by
field: names of any string type with any bytes (UTF8String,
PrintableString with an underscore or an at sign, IA5String,
TeletexString, BMPString of odd length or with a surrogate,
VisibleString, NumericString), an attribute twice or none, no version,
times with a fraction, an extension twice, a compressed EC key, an even
modulus, and any signature. A Signer made so serves Signature and Token.
- Options for the version of a SignerInfo, the hashAlgorithm and the
certHash of an ESSCertIDv2, a signatureAlgorithm other than the one of
the key, a certificate twice, two content-type attributes, an attribute
with an arc of 2^31, a SignerInfo twice, BER, signerInfos out of order,
two signature-time-stamp attributes, and edits of the SignedData and of
each SignerInfo.
- Token options for any accuracy, a genTime of free text, ordering FALSE,
a field after the last, an imprint of any length, no message-digest, a
CRL in crls and the certificate of the authority twice.
- Edits of the DER after signing: Edit, Retag, Withdraw (a SignerInfo
removed), WithoutTimeStamp (a CAdES-T removed), Merge (a co-signature)
and Indefinite.
The tests of internal/cms and internal/der fail for each check of cms.go,
cert.go, verify.go and der.go. A mutation run, which replaces each leaf of
each condition by false and by true, one at a time, kills every mutant
that is not equivalent to the code it mutates.
FuzzParseSignature, FuzzParseToken, FuzzParseCert and FuzzDERCheck, seeded
with security_cms.json and with what cmstest builds: no panic, what Check
accepts Split reads, and the parsers fail only with ErrForm or
ErrAlgorithm.
capsule: the case of a seal outside the validity of the certificate gave
an invalid seal; it now tests a certificate that expired before a valid
seal (out of validity) apart from an authority that was not valid at its
time (invalid seal). SIGNERS out of order, empty, too long, with 31 bytes
or with a hash twice are F1 beside a CMS signature that is valid for the
AUTHOR_MESSAGE of those SIGNERS, and the names of certificates show as
spec v0.12 §29.7 says.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
area [ ] byte
want capsule . Verdict
result string
} {
Tests of the CMS reader: certificates field by field, every check, fuzzing
The builder of the tests, cmstest:
- NewCert writes a certificate from the DER of its tbsCertificate, field by
field: names of any string type with any bytes (UTF8String,
PrintableString with an underscore or an at sign, IA5String,
TeletexString, BMPString of odd length or with a surrogate,
VisibleString, NumericString), an attribute twice or none, no version,
times with a fraction, an extension twice, a compressed EC key, an even
modulus, and any signature. A Signer made so serves Signature and Token.
- Options for the version of a SignerInfo, the hashAlgorithm and the
certHash of an ESSCertIDv2, a signatureAlgorithm other than the one of
the key, a certificate twice, two content-type attributes, an attribute
with an arc of 2^31, a SignerInfo twice, BER, signerInfos out of order,
two signature-time-stamp attributes, and edits of the SignedData and of
each SignerInfo.
- Token options for any accuracy, a genTime of free text, ordering FALSE,
a field after the last, an imprint of any length, no message-digest, a
CRL in crls and the certificate of the authority twice.
- Edits of the DER after signing: Edit, Retag, Withdraw (a SignerInfo
removed), WithoutTimeStamp (a CAdES-T removed), Merge (a co-signature)
and Indefinite.
The tests of internal/cms and internal/der fail for each check of cms.go,
cert.go, verify.go and der.go. A mutation run, which replaces each leaf of
each condition by false and by true, one at a time, kills every mutant
that is not equivalent to the code it mutates.
FuzzParseSignature, FuzzParseToken, FuzzParseCert and FuzzDERCheck, seeded
with security_cms.json and with what cmstest builds: no panic, what Check
accepts Split reads, and the parsers fail only with ErrForm or
ErrAlgorithm.
capsule: the case of a seal outside the validity of the certificate gave
an invalid seal; it now tests a certificate that expired before a valid
seal (out of validity) apart from an authority that was not valid at its
time (invalid seal). SIGNERS out of order, empty, too long, with 31 bytes
or with a hash twice are F1 beside a CMS signature that is valid for the
AUTHOR_MESSAGE of those SIGNERS, and the names of certificates show as
spec v0.12 §29.7 says.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
"a required signer is absent" : { cmsArea ( t , c , [ ] cmstest . Signer { luis } , [ ] cmstest . Signer { ana } , tsa , signedAt , nil ) , capsule . VerdictSignedIncomplete , "absent" } ,
"no seal" : { cmsArea ( t , c , [ ] cmstest . Signer { ana } , [ ] cmstest . Signer { ana } , cmstest . Signer { } , signedAt , nil ) , capsule . VerdictSignedIncomplete , "without seal" } ,
"a certificate out of validity at the time of a valid seal" : { cmsArea ( t , c , [ ] cmstest . Signer { expired } , [ ] cmstest . Signer { expired } , tsa , signedAt , nil ) , capsule . VerdictSignedIncomplete , "out of validity" } ,
"a seal whose authority was not valid at its time" : { cmsArea ( t , c , [ ] cmstest . Signer { ana } , [ ] cmstest . Signer { ana } , tsa , certFrom . AddDate ( - 1 , 0 , 0 ) , nil ) , capsule . VerdictSignedIncomplete , "invalid seal" } ,
"a key outside the table" : { cmsArea ( t , c , [ ] cmstest . Signer { small } , [ ] cmstest . Signer { small } , tsa , signedAt , nil ) , capsule . VerdictSignedIncomplete , "not verifiable" } ,
"a key 3 beside it" : { cmsArea ( t , c , [ ] cmstest . Signer { ana } , [ ] cmstest . Signer { ana } , tsa , signedAt , mustSeal ( t , capsule . SealTypeTest , [ ] byte { 1 } ) ) , capsule . VerdictSignedIncomplete , "valid" } ,
} {
Tests of the CMS reader: certificates field by field, every check, fuzzing
The builder of the tests, cmstest:
- NewCert writes a certificate from the DER of its tbsCertificate, field by
field: names of any string type with any bytes (UTF8String,
PrintableString with an underscore or an at sign, IA5String,
TeletexString, BMPString of odd length or with a surrogate,
VisibleString, NumericString), an attribute twice or none, no version,
times with a fraction, an extension twice, a compressed EC key, an even
modulus, and any signature. A Signer made so serves Signature and Token.
- Options for the version of a SignerInfo, the hashAlgorithm and the
certHash of an ESSCertIDv2, a signatureAlgorithm other than the one of
the key, a certificate twice, two content-type attributes, an attribute
with an arc of 2^31, a SignerInfo twice, BER, signerInfos out of order,
two signature-time-stamp attributes, and edits of the SignedData and of
each SignerInfo.
- Token options for any accuracy, a genTime of free text, ordering FALSE,
a field after the last, an imprint of any length, no message-digest, a
CRL in crls and the certificate of the authority twice.
- Edits of the DER after signing: Edit, Retag, Withdraw (a SignerInfo
removed), WithoutTimeStamp (a CAdES-T removed), Merge (a co-signature)
and Indefinite.
The tests of internal/cms and internal/der fail for each check of cms.go,
cert.go, verify.go and der.go. A mutation run, which replaces each leaf of
each condition by false and by true, one at a time, kills every mutant
that is not equivalent to the code it mutates.
FuzzParseSignature, FuzzParseToken, FuzzParseCert and FuzzDERCheck, seeded
with security_cms.json and with what cmstest builds: no panic, what Check
accepts Split reads, and the parsers fail only with ErrForm or
ErrAlgorithm.
capsule: the case of a seal outside the validity of the certificate gave
an invalid seal; it now tests a certificate that expired before a valid
seal (out of validity) apart from an authority that was not valid at its
time (invalid seal). SIGNERS out of order, empty, too long, with 31 bytes
or with a hash twice are F1 beside a CMS signature that is valid for the
AUTHOR_MESSAGE of those SIGNERS, and the names of certificates show as
spec v0.12 §29.7 says.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
v := capsule . EvaluateSecurityIn ( tc . area , c )
if v . Signature != tc . want || v . Detail == nil || v . Detail . Signers [ 0 ] . Result != tc . result {
t . Errorf ( "%s: %+v, want %s and %q" , name , v , tc . want , tc . result )
continue
}
if lines := v . Lines ( ) ; lines [ 0 ] != capsule . VerdictSignedIncomplete . Text ( ) {
t . Errorf ( "%s: lines %q" , name , lines )
}
}
// Another capsule: the signature does not correspond.
other := testContext ( )
other . HeadDigest [ 5 ] = 9
area := cmsArea ( t , c , [ ] cmstest . Signer { ana } , [ ] cmstest . Signer { ana } , tsa , signedAt , nil )
if got := capsule . EvaluateSecurityIn ( area , other ) . Signature ; got != capsule . VerdictSignatureInvalid {
t . Errorf ( "another head: %s" , got )
}
if got := capsule . EvaluateSecurityIn ( area , nil ) . Signature ; got != capsule . VerdictSignatureUnchecked {
t . Errorf ( "without a context: %s" , got )
}
Tests of the CMS reader: certificates field by field, every check, fuzzing
The builder of the tests, cmstest:
- NewCert writes a certificate from the DER of its tbsCertificate, field by
field: names of any string type with any bytes (UTF8String,
PrintableString with an underscore or an at sign, IA5String,
TeletexString, BMPString of odd length or with a surrogate,
VisibleString, NumericString), an attribute twice or none, no version,
times with a fraction, an extension twice, a compressed EC key, an even
modulus, and any signature. A Signer made so serves Signature and Token.
- Options for the version of a SignerInfo, the hashAlgorithm and the
certHash of an ESSCertIDv2, a signatureAlgorithm other than the one of
the key, a certificate twice, two content-type attributes, an attribute
with an arc of 2^31, a SignerInfo twice, BER, signerInfos out of order,
two signature-time-stamp attributes, and edits of the SignedData and of
each SignerInfo.
- Token options for any accuracy, a genTime of free text, ordering FALSE,
a field after the last, an imprint of any length, no message-digest, a
CRL in crls and the certificate of the authority twice.
- Edits of the DER after signing: Edit, Retag, Withdraw (a SignerInfo
removed), WithoutTimeStamp (a CAdES-T removed), Merge (a co-signature)
and Indefinite.
The tests of internal/cms and internal/der fail for each check of cms.go,
cert.go, verify.go and der.go. A mutation run, which replaces each leaf of
each condition by false and by true, one at a time, kills every mutant
that is not equivalent to the code it mutates.
FuzzParseSignature, FuzzParseToken, FuzzParseCert and FuzzDERCheck, seeded
with security_cms.json and with what cmstest builds: no panic, what Check
accepts Split reads, and the parsers fail only with ErrForm or
ErrAlgorithm.
capsule: the case of a seal outside the validity of the certificate gave
an invalid seal; it now tests a certificate that expired before a valid
seal (out of validity) apart from an authority that was not valid at its
time (invalid seal). SIGNERS out of order, empty, too long, with 31 bytes
or with a hash twice are F1 beside a CMS signature that is valid for the
AUTHOR_MESSAGE of those SIGNERS, and the names of certificates show as
spec v0.12 §29.7 says.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
// F1: SIGNERS out of order, empty, too long, with an element of 31 bytes
// or one twice, each beside a CMS signature that is valid for the
// AUTHOR_MESSAGE of those very SIGNERS: the rule decides, not the CMS.
a , l := sha256Sum ( ana . Cert . Raw ) , sha256Sum ( luis . Cert . Raw )
if bytes . Compare ( a [ : ] , l [ : ] ) > 0 {
a , l = l , a
}
bstr := func ( h [ ] byte ) [ ] byte { return append ( [ ] byte { 0x58 , byte ( len ( h ) ) } , h ... ) }
var seventeen [ ] byte
for range 17 {
seventeen = append ( seventeen , bstr ( a [ : ] ) ... )
}
for name , signers := range map [ string ] [ ] byte {
"SIGNERS out of order" : append ( append ( [ ] byte { 0x82 } , bstr ( l [ : ] ) ... ) , bstr ( a [ : ] ) ... ) ,
"an empty SIGNERS" : { 0x80 } ,
"SIGNERS of 17 entries" : append ( [ ] byte { 0x91 } , seventeen ... ) ,
"SIGNERS with 31 bytes" : append ( [ ] byte { 0x81 } , bstr ( a [ : 31 ] ) ... ) ,
"SIGNERS with one entry twice" : append ( append ( [ ] byte { 0x82 } , bstr ( a [ : ] ) ... ) , bstr ( a [ : ] ) ... ) ,
"SIGNERS of indefinite length" : append ( append ( [ ] byte { 0x9f } , bstr ( a [ : ] ) ... ) , 0xff ) ,
"SIGNERS with a byte after them" : append ( append ( [ ] byte { 0x81 } , bstr ( a [ : ] ) ... ) , 0x00 ) ,
} {
msg := capsule . AuthorMessage ( c . ControlCommit , c . HeadDigest , capsule . SignersDigest ( capsule . AlgCMS , signers ) )
tok := func ( sig [ ] byte ) [ ] byte { return cmstest . Token ( sig , signedAt , cmstest . TokenOptions { } , tsa ) }
content , err := capsule . EncodeAuthorSignature ( capsule . AlgCMS , signers , cmstest . Signature ( msg , cmstest . Options { Token : tok } , ana , luis ) )
if err != nil {
t . Fatal ( err )
}
area , _ := capsule . EncodeSecurityWith ( content , nil )
Tests of the CMS reader: certificates field by field, every check, fuzzing
The builder of the tests, cmstest:
- NewCert writes a certificate from the DER of its tbsCertificate, field by
field: names of any string type with any bytes (UTF8String,
PrintableString with an underscore or an at sign, IA5String,
TeletexString, BMPString of odd length or with a surrogate,
VisibleString, NumericString), an attribute twice or none, no version,
times with a fraction, an extension twice, a compressed EC key, an even
modulus, and any signature. A Signer made so serves Signature and Token.
- Options for the version of a SignerInfo, the hashAlgorithm and the
certHash of an ESSCertIDv2, a signatureAlgorithm other than the one of
the key, a certificate twice, two content-type attributes, an attribute
with an arc of 2^31, a SignerInfo twice, BER, signerInfos out of order,
two signature-time-stamp attributes, and edits of the SignedData and of
each SignerInfo.
- Token options for any accuracy, a genTime of free text, ordering FALSE,
a field after the last, an imprint of any length, no message-digest, a
CRL in crls and the certificate of the authority twice.
- Edits of the DER after signing: Edit, Retag, Withdraw (a SignerInfo
removed), WithoutTimeStamp (a CAdES-T removed), Merge (a co-signature)
and Indefinite.
The tests of internal/cms and internal/der fail for each check of cms.go,
cert.go, verify.go and der.go. A mutation run, which replaces each leaf of
each condition by false and by true, one at a time, kills every mutant
that is not equivalent to the code it mutates.
FuzzParseSignature, FuzzParseToken, FuzzParseCert and FuzzDERCheck, seeded
with security_cms.json and with what cmstest builds: no panic, what Check
accepts Split reads, and the parsers fail only with ErrForm or
ErrAlgorithm.
capsule: the case of a seal outside the validity of the certificate gave
an invalid seal; it now tests a certificate that expired before a valid
seal (out of validity) apart from an authority that was not valid at its
time (invalid seal). SIGNERS out of order, empty, too long, with 31 bytes
or with a hash twice are F1 beside a CMS signature that is valid for the
AUTHOR_MESSAGE of those SIGNERS, and the names of certificates show as
spec v0.12 §29.7 says.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
if v := capsule . EvaluateSecurityIn ( area , c ) ; v . Signature != capsule . VerdictSignatureUnchecked || v . Detail != nil {
t . Errorf ( "%s: %+v" , name , v )
}
}
content , _ := capsule . EncodeAuthorSignature ( capsule . AlgCMS , mustSigners ( t , ana ) , [ ] byte ( "not DER" ) )
area2 , _ := capsule . EncodeSecurityWith ( content , nil )
if got := capsule . EvaluateSecurityIn ( area2 , c ) . Signature ; got != capsule . VerdictSignatureUnchecked {
t . Errorf ( "not a CMS: %s" , got )
}
}
Tests of the CMS reader: certificates field by field, every check, fuzzing
The builder of the tests, cmstest:
- NewCert writes a certificate from the DER of its tbsCertificate, field by
field: names of any string type with any bytes (UTF8String,
PrintableString with an underscore or an at sign, IA5String,
TeletexString, BMPString of odd length or with a surrogate,
VisibleString, NumericString), an attribute twice or none, no version,
times with a fraction, an extension twice, a compressed EC key, an even
modulus, and any signature. A Signer made so serves Signature and Token.
- Options for the version of a SignerInfo, the hashAlgorithm and the
certHash of an ESSCertIDv2, a signatureAlgorithm other than the one of
the key, a certificate twice, two content-type attributes, an attribute
with an arc of 2^31, a SignerInfo twice, BER, signerInfos out of order,
two signature-time-stamp attributes, and edits of the SignedData and of
each SignerInfo.
- Token options for any accuracy, a genTime of free text, ordering FALSE,
a field after the last, an imprint of any length, no message-digest, a
CRL in crls and the certificate of the authority twice.
- Edits of the DER after signing: Edit, Retag, Withdraw (a SignerInfo
removed), WithoutTimeStamp (a CAdES-T removed), Merge (a co-signature)
and Indefinite.
The tests of internal/cms and internal/der fail for each check of cms.go,
cert.go, verify.go and der.go. A mutation run, which replaces each leaf of
each condition by false and by true, one at a time, kills every mutant
that is not equivalent to the code it mutates.
FuzzParseSignature, FuzzParseToken, FuzzParseCert and FuzzDERCheck, seeded
with security_cms.json and with what cmstest builds: no panic, what Check
accepts Split reads, and the parsers fail only with ErrForm or
ErrAlgorithm.
capsule: the case of a seal outside the validity of the certificate gave
an invalid seal; it now tests a certificate that expired before a valid
seal (out of validity) apart from an authority that was not valid at its
time (invalid seal). SIGNERS out of order, empty, too long, with 31 bytes
or with a hash twice are F1 beside a CMS signature that is valid for the
AUTHOR_MESSAGE of those SIGNERS, and the names of certificates show as
spec v0.12 §29.7 says.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
// Spec v0.12 §29.7: a name of a certificate shows when it meets the rules of
// the declared author, has at most 64 code points and no two spaces in a
// row; otherwise the SHA-256 of the certificate shows, or that of the name of
// the issuer for the issuer.
func TestCertificateNamesShown ( t * testing . T ) {
tsa := cmstest . NewECDSA ( "TSA de prueba" , elliptic . P256 ( ) , certFrom , certTo )
c := testContext ( )
sixtyFour := strings . Repeat ( "ñ" , 64 )
for name , tc := range map [ string ] struct {
cn string
shown bool
} {
"a name" : { "Ana López" , true } ,
"64 code points" : { sixtyFour , true } ,
"65 code points" : { sixtyFour + "a" , false } ,
"two spaces in a row" : { "Ana López" , false } ,
"an escape" : { "Ana\x1b[31mLópez" , false } ,
"U+202E" : { "Ana \xe2\x80\xaezepóL" , false } ,
"a byte order mark" : { "\xef\xbb\xbfAna López" , false } ,
"a space at the start" : { " Ana López" , false } ,
"a line feed" : { "Ana\nLópez" , false } ,
"a zero width space" : { "Ana\xe2\x80\x8bLópez" , false } ,
"a tag that spells a text" : { "Ana\xf3\xa0\x81\x81" , false } ,
"an emoji with its selector" : { "Ana \xe2\x9d\xa4\xef\xb8\x8f" , true } ,
"a combining mark, 64 points" : { strings . Repeat ( "n\xcc\x83" , 32 ) , true } ,
} {
s := cmstest . NewCert ( cmstest . CertSpec { CN : tc . cn , Issuer : cmstest . Name ( cmstest . ATV ( cmstest . OIDCommonName , cmstest . UTF8 ( tc . cn ) ) ) } , ecdsaKey ( ) )
v := capsule . EvaluateSecurityIn ( cmsArea ( t , c , [ ] cmstest . Signer { s } , [ ] cmstest . Signer { s } , tsa , signedAt , nil ) , c )
if v . Signature != capsule . VerdictSignedComplete {
t . Fatalf ( "%s: %+v" , name , v )
}
want , issuer := tc . cn , tc . cn
if ! tc . shown {
h , hi := sha256Sum ( s . Cert . Raw ) , sha256Sum ( s . Cert . RawIssuer )
want , issuer = hex . EncodeToString ( h [ : ] ) , hex . EncodeToString ( hi [ : ] )
}
if got := v . Detail . Signers [ 0 ] ; got . Holder != want || got . Issuer != issuer {
t . Errorf ( "%s: holder %q and issuer %q, want %q and %q" , name , got . Holder , got . Issuer , want , issuer )
}
}
}
func ecdsaKey ( ) * ecdsa . PrivateKey { return cmstest . ECKey ( elliptic . P256 ( ) ) }
func mustSigners ( t * testing . T , s cmstest . Signer ) [ ] byte {
t . Helper ( )
b , err := capsule . EncodeSigners ( [ ] [ 32 ] byte { sha256Sum ( s . Cert . Raw ) } )
if err != nil {
t . Fatal ( err )
}
return b
}
func mustSeal ( t * testing . T , typ uint64 , token [ ] byte ) [ ] byte {
t . Helper ( )
b , err := capsule . EncodeSeal ( typ , token )
if err != nil {
t . Fatal ( err )
}
return b
}
func TestEncodeSigners ( t * testing . T ) {
a , b := sha256Sum ( [ ] byte ( "a" ) ) , sha256Sum ( [ ] byte ( "b" ) )
if _ , err := capsule . EncodeSigners ( nil ) ; err == nil {
t . Error ( "an empty list" )
}
if _ , err := capsule . EncodeSigners ( [ ] [ 32 ] byte { a , a } ) ; err == nil {
t . Error ( "a certificate twice" )
}
if _ , err := capsule . EncodeSigners ( make ( [ ] [ 32 ] byte , 17 ) ) ; err == nil {
t . Error ( "17 certificates" )
}
x , _ := capsule . EncodeSigners ( [ ] [ 32 ] byte { a , b } )
y , _ := capsule . EncodeSigners ( [ ] [ 32 ] byte { b , a } )
if string ( x ) != string ( y ) || len ( x ) != 1 + 2 * 34 {
t . Errorf ( "not sorted: %x" , x )
}
}
// Spec v0.11 §29.11: a seal of seal_type 2 seals SEAL_SUBJECT, and gives S4
// before the round time, S5 after it, and S3, S2 and S1 for what does not
// verify, does not decode or uses another hash.
func TestEvaluateSeal ( t * testing . T ) {
tsa := cmstest . NewECDSA ( "Autoridad de Sellado" , elliptic . P256 ( ) , certFrom , certTo )
c := testContext ( )
key , _ := authorkey . Generate ( )
msg := capsule . AuthorMessage ( c . ControlCommit , c . HeadDigest , capsule . SignersDigest ( capsule . AlgEd25519 , nil ) )
sig , _ := capsule . EncodeAuthorSignature ( capsule . AlgEd25519 , key . Public ( ) , key . Sign ( msg ) )
subject := capsule . SealSubject ( c . ControlCommit , c . HeadDigest , capsule . SigPart ( sig ) )
area := func ( token [ ] byte ) [ ] byte {
a , err := capsule . EncodeSecurityWith ( sig , mustSeal ( t , capsule . SealTypeRFC3161 , token ) )
if err != nil {
t . Fatal ( err )
}
return a
}
v := capsule . EvaluateSecurityIn ( area ( cmstest . Token ( subject [ : ] , signedAt , cmstest . TokenOptions { } , tsa ) ) , c )
if v . Signature != capsule . VerdictSignedOther || v . Seal != capsule . VerdictSealed || v . Detail == nil || v . Detail . SealHolder != "Autoridad de Sellado" {
t . Fatalf ( "a valid seal: %+v" , v )
}
if lines := v . Lines ( ) ; len ( lines ) != 2 || ! strings . Contains ( lines [ 1 ] , "Autoridad de Sellado" ) || ! strings . Contains ( lines [ 1 ] , "2026-09-30T12:00:00Z" ) {
t . Errorf ( "lines %q" , v . Lines ( ) )
}
// Sealed with its own signature part: without key 2 the subject differs.
noSig := capsule . SealSubject ( c . ControlCommit , c . HeadDigest , capsule . SigPart ( nil ) )
a , _ := capsule . EncodeSecurityWith ( nil , mustSeal ( t , capsule . SealTypeRFC3161 , cmstest . Token ( noSig [ : ] , signedAt , cmstest . TokenOptions { } , tsa ) ) )
if v := capsule . EvaluateSecurityIn ( a , c ) ; v . Signature != capsule . VerdictNoSignature || v . Seal != capsule . VerdictSealed {
t . Errorf ( "a seal without a signature: %+v" , v )
}
for name , tc := range map [ string ] struct {
token [ ] byte
ctx * capsule . SecurityContext
want capsule . Verdict
} {
"after the round time" : { cmstest . Token ( subject [ : ] , roundTime . Add ( time . Minute ) , cmstest . TokenOptions { } , tsa ) , c , capsule . VerdictSealedLate } ,
"the accuracy reaches it" : { cmstest . Token ( subject [ : ] , roundTime . Add ( - time . Second ) , cmstest . TokenOptions { Accuracy : 2 * time . Second } , tsa ) , c , capsule . VerdictSealedLate } ,
"another subject" : { cmstest . Token ( [ ] byte ( "other" ) , signedAt , cmstest . TokenOptions { } , tsa ) , c , capsule . VerdictSealInvalid } ,
"a TSTInfo of version 2" : { cmstest . Token ( subject [ : ] , signedAt , cmstest . TokenOptions { Version : 2 } , tsa ) , c , capsule . VerdictSealUnreadable } ,
"not DER" : { [ ] byte ( "not DER" ) , c , capsule . VerdictSealUnreadable } ,
"SHA-384 in the imprint" : { cmstest . Token ( subject [ : ] , signedAt , cmstest . TokenOptions { Hash : crypto . SHA384 } , tsa ) , c , capsule . VerdictSealUnsupported } ,
"the TSA expired at its time" : { cmstest . Token ( subject [ : ] , certTo . AddDate ( 1 , 0 , 0 ) , cmstest . TokenOptions { } , tsa ) , c , capsule . VerdictSealInvalid } ,
} {
if got := capsule . EvaluateSecurityIn ( area ( tc . token ) , tc . ctx ) . Seal ; got != tc . want {
t . Errorf ( "%s: %s, want %s" , name , got , tc . want )
}
}
// Without a context, as a reader of v0.10: S1.
if got := capsule . EvaluateSecurity ( area ( cmstest . Token ( subject [ : ] , signedAt , cmstest . TokenOptions { } , tsa ) ) ) . Seal ; got != capsule . VerdictSealUnsupported {
t . Errorf ( "without a context: %s" , got )
}
}
func sha256Sum ( b [ ] byte ) [ 32 ] byte { return sha256 . Sum256 ( b ) }