2024-10-17 14:46:16 +03:00
use super ::common ::Sq ;
#[ test ]
fn sq_pki_link_authorize_then_authenticate ( ) {
let ca_example_org = " <ca@example.org> " ;
for ( e , userids ) in & [
( & [ ] [ .. ] , & [ ca_example_org ] [ .. ] ) ,
// Implicitly use all self-signed user IDs.
( & [ ] , & [ ] ) ,
// Use a non-self signed user ID.
( & [ " --add-userid " ] , & [ " frank " ] ) ,
] {
let mut sq = Sq ::new ( ) ;
let ( ca , ca_pgp , _ca_rev )
= sq . key_generate ( & [ ] , & [ ca_example_org ] ) ;
sq . key_import ( & ca_pgp ) ;
let alice_example_org = " <alice@example.org> " ;
let ( alice , alice_pgp , _alice_rev )
= sq . key_generate ( & [ ] , & [ alice_example_org ] ) ;
sq . key_import ( & alice_pgp ) ;
let bob_example_org = " <bob@example.org> " ;
let bob_other_org = " <bob@other.org> " ;
let ( bob , bob_pgp , _bob_rev )
= sq . key_generate ( & [ ] , & [ bob_example_org , bob_other_org ] ) ;
sq . key_import ( & bob_pgp ) ;
sq . tick ( 1 ) ;
// The ca certifies alice's and bob's certificates for each of
// their user IDs.
let certification = sq . scratch_file ( None ) ;
2024-10-17 18:35:14 +03:00
sq . pki_vouch_certify (
& [ ] ,
ca . key_handle ( ) , alice . key_handle ( ) ,
& [ alice_example_org ] ,
certification . as_path ( ) ) ;
2024-10-17 14:46:16 +03:00
sq . cert_import ( & certification ) ;
let certification = sq . scratch_file ( None ) ;
2024-10-17 18:35:14 +03:00
sq . pki_vouch_certify (
& [ ] ,
ca . key_handle ( ) , bob . key_handle ( ) ,
& [ bob_example_org , bob_other_org ] ,
certification . as_path ( ) ) ;
2024-10-17 14:46:16 +03:00
sq . cert_import ( certification ) ;
// Check whether we can authenticate alice's and bob's
// certificates for their user ID.
let check = | sq : & Sq ,
can_authenticate_alice ,
can_authenticate_bob1 ,
can_authenticate_bob2 |
{
for ( cert , userid , can_authenticate ) in & [
( & alice , alice_example_org , can_authenticate_alice ) ,
( & bob , bob_example_org , can_authenticate_bob1 ) ,
( & bob , bob_other_org , can_authenticate_bob2 ) ,
]
{
let r = sq . pki_authenticate (
& [ ] ,
& cert . fingerprint ( ) . to_string ( ) ,
userid ) ;
match ( can_authenticate , r . is_ok ( ) ) {
( true , false ) = > {
panic! ( " Expected to authenticated {} , but didn't. " ,
userid ) ;
}
( false , true ) = > {
panic! ( " Expected to NOT authenticated {} , but did. " ,
userid ) ;
}
_ = > ( ) ,
}
}
} ;
fn concat < ' a > ( args1 : & [ & ' a str ] , args2 : & [ & ' a str ] )
-> Vec < & ' a str >
{
let mut args = args1 . to_vec ( ) ;
args . extend ( args2 . into_iter ( ) ) ;
args
}
// No delegation yet.
println! ( " CA: not authorized " ) ;
check (
& sq ,
false , // Alice.
false , // bob@example.org
false ) ; // bob@other.org
// The user completely authorizes the CA.
sq . tick ( 1 ) ;
sq . pki_link_authorize ( & concat ( e , & [ " --unconstrained " ] ) ,
ca . key_handle ( ) ,
userids ) ;
println! ( " CA: authorized, and unconstrained " ) ;
check (
& sq ,
true , // alice@example.org
true , // bob@example.org
true ) ; // bob@other.org
// The user authorizes the CA with the regex contraint "example".
sq . tick ( 1 ) ;
sq . pki_link_authorize ( & concat ( e , & [ " --regex " , " example " ] ) ,
ca . key_handle ( ) ,
userids ) ;
println! ( " CA: authorized for \" example \" " ) ;
check (
& sq ,
true , // alice@example.org
true , // bob@example.org
false ) ; // bob@other.org
// The user authorizes the CA with the domain contraint
// "example.org".
sq . tick ( 1 ) ;
sq . pki_link_authorize ( & concat ( e , & [ " --domain " , " example.org " ] ) ,
ca . key_handle ( ) ,
userids ) ;
println! ( " CA: authorized for \" example.org \" " ) ;
check (
& sq ,
true , // alice@example.org
true , // bob@example.org
false ) ; // bob@other.org
// The user authorizes the CA with the regex contraint "other".
sq . tick ( 1 ) ;
sq . pki_link_authorize ( & concat ( e , & [ " --regex " , " other " ] ) ,
ca . key_handle ( ) ,
userids ) ;
println! ( " CA: authorized for \" other \" " ) ;
check (
& sq ,
false , // alice@example.org
false , // bob@example.org
true ) ; // bob@other.org
// The user authorizes the CA with the regex contraint "bob".
sq . tick ( 1 ) ;
sq . pki_link_authorize ( & concat ( e , & [ " --regex " , " bob " ] ) ,
ca . key_handle ( ) ,
userids ) ;
println! ( " CA: authorized for \" bob \" " ) ;
check (
& sq ,
false , // alice@example.org
true , // bob@example.org
true ) ; // bob@other.org
// The user authorizes the CA with the regex contraint "bob" or
// "alice".
sq . tick ( 1 ) ;
sq . pki_link_authorize ( & concat ( e , & [ " --regex " , " bob " ,
" --regex " , " alice " ] ) ,
ca . key_handle ( ) ,
userids ) ;
println! ( " CA: authorized for \" bob \" or \" alice \" " ) ;
check (
& sq ,
true , // alice@example.org
true , // bob@example.org
true ) ; // bob@other.org
// The user authorizes the CA for the domains example.org and
// other.org.
sq . tick ( 1 ) ;
sq . pki_link_authorize ( & concat ( e , & [ " --domain " , " example.org " ,
" --domain " , " other.org " ] ) ,
ca . key_handle ( ) ,
userids ) ;
println! ( " CA: authorized for the domains example.org and other.org " ) ;
check (
& sq ,
true , // alice@example.org
true , // bob@example.org
true ) ; // bob@other.org
// The user authorizes the CA for the domain example.com and the
// regex alice.
sq . tick ( 1 ) ;
sq . pki_link_authorize ( & concat ( e , & [ " --domain " , " other.org " ,
" --regex " , " alice " ] ) ,
ca . key_handle ( ) ,
userids ) ;
println! ( " CA: authorized for the domains example.org and other.org " ) ;
check (
& sq ,
true , // alice@example.org
false , // bob@example.org
true ) ; // bob@other.org
// The user authorizes the CA with the regex contraint "zoo".
sq . tick ( 1 ) ;
sq . pki_link_authorize ( & concat ( e , & [ " --regex " , " zoo " ] ) ,
ca . key_handle ( ) ,
userids ) ;
println! ( " CA: authorized for \" zoo \" " ) ;
check (
& sq ,
false , // alice@example.org
false , // bob@example.org
false ) ; // bob@other.org
// The user authorizes the CA with the domain contraint "example".
sq . tick ( 1 ) ;
sq . pki_link_authorize ( & concat ( e , & [ " --domain " , " example " ] ) ,
ca . key_handle ( ) ,
userids ) ;
println! ( " CA: authorized for \" zoo \" " ) ;
check (
& sq ,
false , // alice@example.org
false , // bob@example.org
false ) ; // bob@other.org
}
}
#[ test ]
fn retract_explicit ( ) {
// Authorize a CA via multiple user IDs. Retract one
// authorization at a time. Make sure the CA remains a trusted
// introducer until all authorizations are retracted.
let ca_example_org = " <ca@example.org> " ;
let ca_example_com = " <ca@example.com> " ;
let self_signed_userids = & [ ca_example_org , ca_example_com ] [ .. ] ;
// When authorizing the CA we can either authorize implicitly
// (i.e., all self-signed user IDs) or explicitly. Try both.
for implicit_all in [ true , false ] {
eprintln! ( " implicit all = {} " , implicit_all ) ;
let mut sq = Sq ::new ( ) ;
let ( ca , ca_pgp , _ca_rev )
= sq . key_generate ( & [ ] , self_signed_userids ) ;
sq . key_import ( & ca_pgp ) ;
let alice_example_org = " <alice@example.org> " ;
let ( alice , alice_pgp , _alice_rev )
= sq . key_generate ( & [ ] , & [ alice_example_org ] ) ;
sq . key_import ( & alice_pgp ) ;
sq . tick ( 1 ) ;
// The ca certifies alice's certificate
let certification = sq . scratch_file ( None ) ;
2024-10-17 18:35:14 +03:00
sq . pki_vouch_certify ( & [ ] ,
ca . key_handle ( ) , alice . key_handle ( ) ,
& [ alice_example_org ] ,
certification . as_path ( ) ) ;
2024-10-17 14:46:16 +03:00
sq . cert_import ( & certification ) ;
let check = | sq : & Sq , can_authenticate : bool | {
let r = sq . pki_authenticate (
& [ ] ,
& alice . fingerprint ( ) . to_string ( ) ,
alice_example_org ) ;
match ( can_authenticate , r . is_ok ( ) ) {
( true , false ) = > {
panic! ( " Expected to authenticated {} , but didn't. " ,
alice_example_org ) ;
}
( false , true ) = > {
panic! ( " Expected to NOT authenticated {} , but did. " ,
alice_example_org ) ;
}
_ = > ( ) ,
}
} ;
// The ca is not yet authorized so we shouldn't be able to
// authenticate alice.
check ( & sq , false ) ;
// Authorize via all user IDs.
sq . tick ( 1 ) ;
let userids = self_signed_userids ;
sq . pki_link_authorize ( & [ " --unconstrained " ] ,
ca . key_handle ( ) ,
if implicit_all {
& [ ]
} else {
userids
} ) ;
check ( & sq , true ) ;
for ( i , userid ) in userids . iter ( ) . enumerate ( ) {
// Retract the authorization of one user ID. It should
// still be a trusted introducer.
sq . tick ( 1 ) ;
sq . pki_link_retract ( & [ ] , ca . key_handle ( ) , & [ userid ] ) ;
if i = = userids . len ( ) - 1 {
// We've retracted all authorizations. This should
// now fail.
check ( & sq , false ) ;
} else {
check ( & sq , true ) ;
}
}
}
}
#[ test ]
fn retract_non_self_signed ( ) {
// Make sure we can retract non-self-signed user IDs.
let self_signed = " <ca@example.org> " ;
let non_self_signed = " <ca@example.com> " ;
let mut sq = Sq ::new ( ) ;
let ( ca , ca_pgp , _ca_rev )
= sq . key_generate ( & [ ] , & [ self_signed ] ) ;
sq . key_import ( & ca_pgp ) ;
let alice_example_org = " <alice@example.org> " ;
let ( alice , alice_pgp , _alice_rev )
= sq . key_generate ( & [ ] , & [ alice_example_org ] ) ;
sq . key_import ( & alice_pgp ) ;
sq . tick ( 1 ) ;
// The ca certifies alice's certificate
let certification = sq . scratch_file ( None ) ;
2024-10-17 18:35:14 +03:00
sq . pki_vouch_certify ( & [ ] ,
ca . key_handle ( ) , alice . key_handle ( ) ,
& [ alice_example_org ] ,
certification . as_path ( ) ) ;
2024-10-17 14:46:16 +03:00
sq . cert_import ( & certification ) ;
let check = | sq : & Sq , can_authenticate : bool | {
let r = sq . pki_authenticate (
& [ ] ,
& alice . fingerprint ( ) . to_string ( ) ,
alice_example_org ) ;
match ( can_authenticate , r . is_ok ( ) ) {
( true , false ) = > {
panic! ( " Expected to authenticated {} , but didn't. " ,
alice_example_org ) ;
}
( false , true ) = > {
panic! ( " Expected to NOT authenticated {} , but did. " ,
alice_example_org ) ;
}
_ = > ( ) ,
}
} ;
// The ca is not yet authorized so we shouldn't be able to
// authenticate alice.
check ( & sq , false ) ;
// Authorize the CA via a non-self-signed user ID. Now we can
// authenticate alice.
sq . tick ( 1 ) ;
sq . pki_link_authorize ( & [ " --unconstrained " , " --add-userid " ] ,
ca . key_handle ( ) ,
& [ non_self_signed ] ) ;
check ( & sq , true ) ;
// Retract the authorization. It should no longer be considered a
// trusted introducer.
sq . tick ( 1 ) ;
sq . pki_link_retract ( & [ ] , ca . key_handle ( ) , & [ non_self_signed ] ) ;
check ( & sq , false ) ;
}
#[ test ]
fn retract_all ( ) {
// Link all self-signed user IDs and a non-self-signed user ID.
// When we retract all, make sure they are all retracted.
let self_signed = " <ca@example.org> " ;
let non_self_signed = " <ca@example.com> " ;
let mut sq = Sq ::new ( ) ;
let ( ca , ca_pgp , _ca_rev )
= sq . key_generate ( & [ ] , & [ self_signed ] ) ;
sq . key_import ( & ca_pgp ) ;
let alice_example_org = " <alice@example.org> " ;
let ( alice , alice_pgp , _alice_rev )
= sq . key_generate ( & [ ] , & [ alice_example_org ] ) ;
sq . key_import ( & alice_pgp ) ;
sq . tick ( 1 ) ;
// The ca certifies alice's certificate
let certification = sq . scratch_file ( None ) ;
2024-10-17 18:35:14 +03:00
sq . pki_vouch_certify ( & [ ] ,
ca . key_handle ( ) , alice . key_handle ( ) ,
& [ alice_example_org ] ,
certification . as_path ( ) ) ;
2024-10-17 14:46:16 +03:00
sq . cert_import ( & certification ) ;
let check = | sq : & Sq , can_authenticate : bool | {
let r = sq . pki_authenticate (
& [ ] ,
& alice . fingerprint ( ) . to_string ( ) ,
alice_example_org ) ;
match ( can_authenticate , r . is_ok ( ) ) {
( true , false ) = > {
panic! ( " Expected to authenticated {} , but didn't. " ,
alice_example_org ) ;
}
( false , true ) = > {
panic! ( " Expected to NOT authenticated {} , but did. " ,
alice_example_org ) ;
}
_ = > ( ) ,
}
} ;
// The ca is not yet authorized so we shouldn't be able to
// authenticate alice.
check ( & sq , false ) ;
// Authorize the CA via a non-self-signed user ID. Now we can
// authenticate alice.
sq . tick ( 1 ) ;
sq . pki_link_authorize ( & [ " --unconstrained " , " --add-userid " ] ,
ca . key_handle ( ) ,
& [ self_signed , non_self_signed ] ) ;
check ( & sq , true ) ;
// Retract all authorizations. It should no longer be considered
// a trusted introducer.
sq . tick ( 1 ) ;
sq . pki_link_retract ( & [ ] , ca . key_handle ( ) , & [ ] ) ;
check ( & sq , false ) ;
}
2024-10-18 10:45:08 +03:00
#[ test ]
fn sq_pki_link_all_revoked ( ) {
// When we don't provide any user IDs, `sq pki link authorize`
// certifies all of the self signed user IDs. Make sure this
// works in the presence of a revoked user ID, which should be
// ignored.
let mut sq = Sq ::new ( ) ;
let ca_example_org = " <ca@example.org> " ;
let ca_example_com = " <ca@example.com> " ;
let ( ca , ca_pgp , _ca_rev )
= sq . key_generate ( & [ ] , & [ ca_example_org , ca_example_com ] ) ;
sq . key_import ( & ca_pgp ) ;
// Revoke ca@example.com.
sq . tick ( 1 ) ;
let revocation = sq . scratch_file ( " revocation " ) ;
sq . key_userid_revoke ( & [ ] , ca . fingerprint ( ) , ca_example_com ,
" retired " , " bye " , Some ( revocation . as_path ( ) ) ) ;
sq . cert_import ( & revocation ) ;
let alice_example_org = " <alice@example.org> " ;
let ( alice , alice_pgp , _alice_rev )
= sq . key_generate ( & [ ] , & [ alice_example_org ] ) ;
sq . key_import ( & alice_pgp ) ;
sq . tick ( 1 ) ;
// The ca certifies alice's certificate.
let certification = sq . scratch_file ( None ) ;
sq . pki_vouch_certify (
& [ ] ,
ca . key_handle ( ) , alice . key_handle ( ) ,
& [ alice_example_org ] ,
certification . as_path ( ) ) ;
sq . cert_import ( & certification ) ;
// Check whether we can authenticate alice's and bob's
// certificates for their user ID using otto as the trust root.
let check = | sq : & Sq , can_authenticate |
{
let r = sq . pki_authenticate (
& [ ] ,
& alice . fingerprint ( ) . to_string ( ) ,
alice_example_org ) ;
match ( can_authenticate , r . is_ok ( ) ) {
( true , false ) = > {
panic! ( " Expected to authenticated {} , but didn't. " ,
alice_example_org ) ;
}
( false , true ) = > {
panic! ( " Expected to NOT authenticated {} , but did. " ,
alice_example_org ) ;
}
_ = > ( ) ,
}
} ;
// No delegation yet.
println! ( " CA: not authorized " ) ;
check ( & sq , false ) ;
// The user completely authorizes the CA. Note: we don't specify
// any user IDs so only valid self-signed user IDs should be used.
// That means the revoked user ID should be skipped.
sq . tick ( 1 ) ;
sq . pki_link_authorize ( & [ " --unconstrained " ] ,
ca . key_handle ( ) , & [ ] ) ;
println! ( " CA: authorized, and unconstrained " ) ;
check ( & sq , true ) ;
}