@ -1673,3 +1673,141 @@ func TestAuthority_constraints(t *testing.T) {
} )
}
}
func TestAuthority_CRL ( t * testing . T ) {
reasonCode := 2
reason := "bob was let go"
validIssuer := "step-cli"
validAudience := testAudiences . Revoke
now := time . Now ( ) . UTC ( )
//
jwk , err := jose . ReadKey ( "testdata/secrets/step_cli_key_priv.jwk" , jose . WithPassword ( [ ] byte ( "pass" ) ) )
assert . FatalError ( t , err )
//
sig , err := jose . NewSigner ( jose . SigningKey { Algorithm : jose . ES256 , Key : jwk . Key } ,
( & jose . SignerOptions { } ) . WithType ( "JWT" ) . WithHeader ( "kid" , jwk . KeyID ) )
assert . FatalError ( t , err )
crlCtx := provisioner . NewContextWithMethod ( context . Background ( ) , provisioner . RevokeMethod )
var crlStore db . CertificateRevocationListInfo
var revokedList [ ] db . RevokedCertificateInfo
type test struct {
auth * Authority
ctx context . Context
expected [ ] string
err error
code int
}
tests := map [ string ] func ( ) test {
"ok/empty-crl" : func ( ) test {
_a := testAuthority ( t , WithDatabase ( & db . MockAuthDB {
MUseToken : func ( id , tok string ) ( bool , error ) {
return true , nil
} ,
MGetCertificate : func ( sn string ) ( * x509 . Certificate , error ) {
return nil , errors . New ( "not found" )
} ,
MStoreCRL : func ( i * db . CertificateRevocationListInfo ) error {
crlStore = * i
return nil
} ,
MGetCRL : func ( ) ( * db . CertificateRevocationListInfo , error ) {
return & crlStore , nil
} ,
MGetRevokedCertificates : func ( ) ( * [ ] db . RevokedCertificateInfo , error ) {
return & revokedList , nil
} ,
MRevoke : func ( rci * db . RevokedCertificateInfo ) error {
revokedList = append ( revokedList , * rci )
return nil
} ,
} ) )
return test {
auth : _a ,
ctx : crlCtx ,
expected : nil ,
}
} ,
"ok/crl-full" : func ( ) test {
_a := testAuthority ( t , WithDatabase ( & db . MockAuthDB {
MUseToken : func ( id , tok string ) ( bool , error ) {
return true , nil
} ,
MGetCertificate : func ( sn string ) ( * x509 . Certificate , error ) {
return nil , errors . New ( "not found" )
} ,
MStoreCRL : func ( i * db . CertificateRevocationListInfo ) error {
crlStore = * i
return nil
} ,
MGetCRL : func ( ) ( * db . CertificateRevocationListInfo , error ) {
return & crlStore , nil
} ,
MGetRevokedCertificates : func ( ) ( * [ ] db . RevokedCertificateInfo , error ) {
return & revokedList , nil
} ,
MRevoke : func ( rci * db . RevokedCertificateInfo ) error {
revokedList = append ( revokedList , * rci )
return nil
} ,
} ) )
var ex [ ] string
for i := 0 ; i < 100 ; i ++ {
sn := fmt . Sprintf ( "%v" , i )
cl := jwt . Claims {
Subject : fmt . Sprintf ( "sn-%v" , i ) ,
Issuer : validIssuer ,
NotBefore : jwt . NewNumericDate ( now ) ,
Expiry : jwt . NewNumericDate ( now . Add ( time . Minute ) ) ,
Audience : validAudience ,
ID : sn ,
}
raw , err := jwt . Signed ( sig ) . Claims ( cl ) . CompactSerialize ( )
assert . FatalError ( t , err )
err = _a . Revoke ( crlCtx , & RevokeOptions {
Serial : sn ,
ReasonCode : reasonCode ,
Reason : reason ,
OTT : raw ,
} )
assert . FatalError ( t , err )
ex = append ( ex , sn )
}
return test {
auth : _a ,
ctx : crlCtx ,
expected : ex ,
}
} ,
}
for name , f := range tests {
tc := f ( )
t . Run ( name , func ( t * testing . T ) {
if crlBytes , _err := tc . auth . GetCertificateRevocationList ( ) ; _err == nil {
crl , parseErr := x509 . ParseCRL ( crlBytes )
if parseErr != nil {
t . Errorf ( "x509.ParseCertificateRequest() error = %v, wantErr %v" , parseErr , nil )
}
var cmpList [ ] string
for _ , c := range crl . TBSCertList . RevokedCertificates {
cmpList = append ( cmpList , c . SerialNumber . String ( ) )
}
assert . Equals ( t , cmpList , tc . expected )
} else {
assert . NotNil ( t , tc . err )
}
} )
}
}