55//!
66//! The following example shows how to do all these in a single example:
77//! start and SSH agent server, connect to it with a client, decipher
8- //! an encrypted private key (the password is `b"blabla"`), send it to
8+ //! an encrypted ED25519 private key (the password is `b"blabla"`), send it to
99//! the agent, and ask the agent to sign a piece of data
1010//! (`b"Please sign this"`, below).
1111//!
2121//! }
2222//! }
2323//!
24- //! const PKCS8_ENCRYPTED: &'static str = "-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQITo1O0b8YrS0CAggA\nMAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBBtLH4T1KOfo1GGr7salhR8BIIE\n0KN9ednYwcTGSX3hg7fROhTw7JAJ1D4IdT1fsoGeNu2BFuIgF3cthGHe6S5zceI2\nMpkfwvHbsOlDFWMUIAb/VY8/iYxhNmd5J6NStMYRC9NC0fVzOmrJqE1wITqxtORx\nIkzqkgFUbaaiFFQPepsh5CvQfAgGEWV329SsTOKIgyTj97RxfZIKA+TR5J5g2dJY\nj346SvHhSxJ4Jc0asccgMb0HGh9UUDzDSql0OIdbnZW5KzYJPOx+aDqnpbz7UzY/\nP8N0w/pEiGmkdkNyvGsdttcjFpOWlLnLDhtLx8dDwi/sbEYHtpMzsYC9jPn3hnds\nTcotqjoSZ31O6rJD4z18FOQb4iZs3MohwEdDd9XKblTfYKM62aQJWH6cVQcg+1C7\njX9l2wmyK26Tkkl5Qg/qSfzrCveke5muZgZkFwL0GCcgPJ8RixSB4GOdSMa/hAMU\nkvFAtoV2GluIgmSe1pG5cNMhurxM1dPPf4WnD+9hkFFSsMkTAuxDZIdDk3FA8zof\nYhv0ZTfvT6V+vgH3Hv7Tqcxomy5Qr3tj5vvAqqDU6k7fC4FvkxDh2mG5ovWvc4Nb\nXv8sed0LGpYitIOMldu6650LoZAqJVv5N4cAA2Edqldf7S2Iz1QnA/usXkQd4tLa\nZ80+sDNv9eCVkfaJ6kOVLk/ghLdXWJYRLenfQZtVUXrPkaPpNXgD0dlaTN8KuvML\nUw/UGa+4ybnPsdVflI0YkJKbxouhp4iB4S5ACAwqHVmsH5GRnujf10qLoS7RjDAl\no/wSHxdT9BECp7TT8ID65u2mlJvH13iJbktPczGXt07nBiBse6OxsClfBtHkRLzE\nQF6UMEXsJnIIMRfrZQnduC8FUOkfPOSXc8r9SeZ3GhfbV/DmWZvFPCpjzKYPsM5+\nN8Bw/iZ7NIH4xzNOgwdp5BzjH9hRtCt4sUKVVlWfEDtTnkHNOusQGKu7HkBF87YZ\nRN/Nd3gvHob668JOcGchcOzcsqsgzhGMD8+G9T9oZkFCYtwUXQU2XjMN0R4VtQgZ\nrAxWyQau9xXMGyDC67gQ5xSn+oqMK0HmoW8jh2LG/cUowHFAkUxdzGadnjGhMOI2\nzwNJPIjF93eDF/+zW5E1l0iGdiYyHkJbWSvcCuvTwma9FIDB45vOh5mSR+YjjSM5\nnq3THSWNi7Cxqz12Q1+i9pz92T2myYKBBtu1WDh+2KOn5DUkfEadY5SsIu/Rb7ub\n5FBihk2RN3y/iZk+36I69HgGg1OElYjps3D+A9AjVby10zxxLAz8U28YqJZm4wA/\nT0HLxBiVw+rsHmLP79KvsT2+b4Diqih+VTXouPWC/W+lELYKSlqnJCat77IxgM9e\nYIhzD47OgWl33GJ/R10+RDoDvY4koYE+V5NLglEhbwjloo9Ryv5ywBJNS7mfXMsK\n/uf+l2AscZTZ1mhtL38efTQCIRjyFHc3V31DI0UdETADi+/Omz+bXu0D5VvX+7c6\nb1iVZKpJw8KUjzeUV8yOZhvGu3LrQbhkTPVYL555iP1KN0Eya88ra+FUKMwLgjYr\nJkUx4iad4dTsGPodwEP/Y9oX/Qk3ZQr+REZ8lg6IBoKKqqrQeBJ9gkm1jfKE6Xkc\nCog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux\n-----END ENCRYPTED PRIVATE KEY-----\n";
24+ //! const PKCS8_ENCRYPTED: &'static str = "-----BEGIN ENCRYPTED PRIVATE KEY-----\nMIGjMF8GCSqGSIb3DQEFDTBSMDEGCSqGSIb3DQEFDDAkBBAWQiUHKoocuxfoZ/hF\nYTjkAgIIADAMBggqhkiG9w0CCQUAMB0GCWCGSAFlAwQBKgQQ83d1d5/S2wz475uC\nCUrE7QRAvdVpD5e3zKH/MZjilWrMOm6cyI1LKBCssLztPyvOALtroLAPlp7WYWfu\n9Sncmm7u14n2lia7r1r5I3VBsVuH0g==\n-----END ENCRYPTED PRIVATE KEY-----\n";
2525//!
2626//! #[cfg(unix)]
2727//! fn main() {
@@ -137,6 +137,7 @@ pub enum Error {
137137 #[ error( transparent) ]
138138 IO ( #[ from] std:: io:: Error ) ,
139139
140+ #[ cfg( feature = "rsa" ) ]
140141 #[ error( "Rsa: {0}" ) ]
141142 Rsa ( #[ from] rsa:: Error ) ,
142143
@@ -152,6 +153,7 @@ pub enum Error {
152153 Der ( #[ from] der:: Error ) ,
153154 #[ error( "Spki: {0}" ) ]
154155 Spki ( #[ from] spki:: Error ) ,
156+ #[ cfg( feature = "rsa" ) ]
155157 #[ error( "Pkcs1: {0}" ) ]
156158 Pkcs1 ( #[ from] pkcs1:: Error ) ,
157159 #[ error( "Pkcs8: {0}" ) ]
@@ -301,6 +303,7 @@ dP3jryYgvsCIBAA5jMWSjrmnOTXhidqcOy4xYCrAttzSnZ/cUadfBenL+DQq6neffw7j8r
301303sJWR7W+cGvJ/vLsw==
302304-----END OPENSSH PRIVATE KEY-----" ;
303305
306+ #[ cfg( feature = "rsa" ) ]
304307 const RSA_KEY : & str = "-----BEGIN OPENSSH PRIVATE KEY-----
305308b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
306309NhAAAAAwEAAQAAAQEAuSvQ9m76zhRB4m0BUKPf17lwccj7KQ1Qtse63AOqP/VYItqEH8un
@@ -377,6 +380,7 @@ Z9w7lshQhqowtrbLDFw4rXAxZuE=
377380 // We can't encode attributes, skip test_decode_encode_symmetry.
378381 }
379382
383+ #[ cfg( feature = "rsa" ) ]
380384 #[ test]
381385 fn test_decode_rsa_secret_key ( ) {
382386 env_logger:: try_init ( ) . unwrap_or ( ( ) ) ;
@@ -509,6 +513,7 @@ Ve0k2ddxoEsSE15H4lgNHM2iuYKzIqZJOReHRCTff6QGgMYPDqDfFfL1Hc1Ntql0pwAAAA
509513 parse_public_key_base64 ( key) . unwrap ( ) ;
510514 }
511515
516+ #[ cfg( feature = "rsa" ) ]
512517 #[ test]
513518 fn test_nikao ( ) {
514519 env_logger:: try_init ( ) . unwrap_or ( ( ) ) ;
@@ -543,6 +548,7 @@ QaChXiDsryJZwsRnruvMRX9nedtqHrgnIsJLTXjppIhGhq5Kg4RQfOU=
543548 decode_secret_key ( key, None ) . unwrap ( ) ;
544549 }
545550
551+ #[ cfg( feature = "rsa" ) ]
546552 #[ test]
547553 fn test_decode_pkcs8_rsa_secret_key ( ) {
548554 // Generated using: ssh-keygen -t rsa -b 1024 -m pkcs8 -f $file
680686 assert_eq ! ( original_key_bytes, encoded_key_bytes) ;
681687 }
682688
689+ #[ cfg( feature = "rsa" ) ]
683690 #[ test]
684691 fn test_o01eg ( ) {
685692 env_logger:: try_init ( ) . unwrap_or ( ( ) ) ;
@@ -718,6 +725,7 @@ br8gXU8KyiY9sZVbmplRPF+ar462zcI2kt0a18mr0vbrdqp2eMjb37QDbVBJ+rPE
718725 decode_secret_key ( key, Some ( "12345" ) ) . unwrap ( ) ;
719726 }
720727
728+ #[ cfg( feature = "rsa" ) ]
721729 pub const PKCS8_RSA : & str = "-----BEGIN RSA PRIVATE KEY-----
722730MIIEpAIBAAKCAQEAwBGetHjW+3bDQpVktdemnk7JXgu1NBWUM+ysifYLDBvJ9ttX
723731GNZSyQKA4v/dNr0FhAJ8I9BuOTjYCy1YfKylhl5D/DiSSXFPsQzERMmGgAlYvU2U
@@ -747,13 +755,15 @@ xV/JrzLAwPoKk3bkqys3bUmgo6DxVC/6RmMwPQ0rmpw78kOgEej90g==
747755-----END RSA PRIVATE KEY-----
748756" ;
749757
758+ #[ cfg( feature = "rsa" ) ]
750759 #[ test]
751760 fn test_pkcs8 ( ) {
752761 env_logger:: try_init ( ) . unwrap_or ( ( ) ) ;
753762 println ! ( "test" ) ;
754763 decode_secret_key ( PKCS8_RSA , Some ( "blabla" ) ) . unwrap ( ) ;
755764 }
756765
766+ #[ cfg( feature = "rsa" ) ]
757767 const PKCS8_ENCRYPTED : & str = "-----BEGIN ENCRYPTED PRIVATE KEY-----
758768MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQITo1O0b8YrS0CAggA
759769MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBBtLH4T1KOfo1GGr7salhR8BIIE
@@ -815,6 +825,7 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux
815825 ssh_key:: PublicKey :: decode ( & key) . unwrap ( ) ;
816826 }
817827
828+ #[ cfg( feature = "rsa" ) ]
818829 #[ test]
819830 fn test_pkcs8_encrypted ( ) {
820831 env_logger:: try_init ( ) . unwrap_or ( ( ) ) ;
@@ -877,21 +888,21 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux
877888 }
878889
879890 #[ tokio:: test]
880- #[ cfg( unix) ]
891+ #[ cfg( all ( unix, feature = "rsa" ) ) ]
881892 async fn test_client_agent_rsa ( ) {
882893 let key = decode_secret_key ( PKCS8_ENCRYPTED , Some ( "blabla" ) ) . unwrap ( ) ;
883894 test_client_agent ( key) . await . expect ( "ssh-agent test failed" )
884895 }
885896
886897 #[ tokio:: test]
887- #[ cfg( unix) ]
898+ #[ cfg( all ( unix, feature = "rsa" ) ) ]
888899 async fn test_client_agent_openssh_rsa ( ) {
889900 let key = decode_secret_key ( RSA_KEY , None ) . unwrap ( ) ;
890901 test_client_agent ( key) . await . expect ( "ssh-agent test failed" )
891902 }
892903
893904 #[ test]
894- #[ cfg( unix) ]
905+ #[ cfg( all ( unix, feature = "rsa" ) ) ]
895906 fn test_agent ( ) {
896907 env_logger:: try_init ( ) . unwrap_or ( ( ) ) ;
897908 let dir = tempfile:: tempdir ( ) . unwrap ( ) ;
@@ -912,9 +923,10 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux
912923 }
913924 }
914925 let agent_path_ = agent_path. clone ( ) ;
926+ let ( tx, rx) = tokio:: sync:: oneshot:: channel ( ) ;
915927 core. spawn ( async move {
916928 let mut listener = tokio:: net:: UnixListener :: bind ( & agent_path_) . unwrap ( ) ;
917-
929+ let _ = tx . send ( ( ) ) ;
918930 agent:: server:: serve (
919931 Incoming {
920932 listener : & mut listener,
@@ -923,9 +935,12 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux
923935 )
924936 . await
925937 } ) ;
938+
926939 let key = decode_secret_key ( PKCS8_ENCRYPTED , Some ( "blabla" ) ) . unwrap ( ) ;
927940 core. block_on ( async move {
928941 let public = key. public_key ( ) ;
942+ // make sure the listener created the file handle
943+ rx. await . unwrap ( ) ;
929944 let stream = tokio:: net:: UnixStream :: connect ( & agent_path) . await . unwrap ( ) ;
930945 let mut client = agent:: client:: AgentClient :: connect ( stream) ;
931946 client
0 commit comments