@@ -264,18 +264,23 @@ impl PublicKey {
264
264
265
265
fn try_key_parse ( key : & str ) -> Result < Self > {
266
266
// then parse the key according to rfc4253
267
- let mut parts = key. split_whitespace ( ) ;
268
- let keytype = parts. next ( ) . ok_or ( OpenSSHKeyError :: InvalidFormat ) ?;
269
- let data = parts. next ( ) . ok_or ( OpenSSHKeyError :: InvalidFormat ) ?;
270
- // comment is not required. if we get an empty comment (because of a
271
- // trailing space) throw it out.
272
- let comment = parts. next ( ) . and_then ( |c| {
273
- if c. is_empty ( ) {
274
- None
275
- } else {
276
- Some ( c. to_string ( ) )
277
- }
278
- } ) ;
267
+ let ( keytype, remaining) = key
268
+ . split_once ( char:: is_whitespace)
269
+ . ok_or ( OpenSSHKeyError :: InvalidFormat ) ?;
270
+
271
+ let ( data, comment) = remaining
272
+ . split_once ( char:: is_whitespace)
273
+ . unwrap_or ( ( remaining, "" ) ) ;
274
+
275
+ let comment = comment. trim ( ) ;
276
+ if comment. contains ( '\n' ) {
277
+ return Err ( OpenSSHKeyError :: InvalidFormat ) ;
278
+ }
279
+ let comment = if comment. is_empty ( ) {
280
+ None
281
+ } else {
282
+ Some ( comment. to_owned ( ) )
283
+ } ;
279
284
280
285
let buf = BASE64
281
286
. decode ( data)
@@ -611,7 +616,7 @@ impl PublicKey {
611
616
/// `fb:a0:5b:a0:21:01:47:33:3b:8d:9e:14:1a:4c:db:6d` .
612
617
pub fn fingerprint_md5 ( & self ) -> String {
613
618
let mut sh = Md5 :: default ( ) ;
614
- sh. update ( & self . data ( ) ) ;
619
+ sh. update ( self . data ( ) ) ;
615
620
616
621
let md5: Vec < String > = sh. finalize ( ) . iter ( ) . map ( |n| format ! ( "{:02x}" , n) ) . collect ( ) ;
617
622
md5. join ( ":" )
@@ -983,4 +988,68 @@ ssh-dss AAAAB3NzaC1kc3MAAACBAIkd9CkqldM2St8f53rfJT7kPgiA8leZaN7hdZd48hYJyKzVLoPd
983
988
assert_eq ! ( key2, keys[ 1 ] . to_string( ) ) ;
984
989
assert_eq ! ( key3, keys[ 2 ] . to_string( ) ) ;
985
990
}
991
+
992
+ #[ test]
993
+ fn comment_should_be_none_when_absent ( ) {
994
+ let key =
995
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAhBr6++FQXB8kkgOMbdxBuyrHzuX5HkElswrN6DQoN/" ;
996
+ let key = PublicKey :: parse ( key) . unwrap ( ) ;
997
+ assert ! ( key. comment. is_none( ) ) ;
998
+ }
999
+
1000
+ #[ test]
1001
+ fn comment_should_be_none_when_empty_string ( ) {
1002
+ let key =
1003
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAhBr6++FQXB8kkgOMbdxBuyrHzuX5HkElswrN6DQoN/ " ;
1004
+ let key = PublicKey :: parse ( key) . unwrap ( ) ;
1005
+ assert ! ( key. comment. is_none( ) ) ;
1006
+ }
1007
+
1008
+ #[ test]
1009
+ fn comment_should_preserve_special_characters ( ) {
1010
+ let key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAhBr6++FQXB8kkgOMbdxBuyrHzuX5HkElswrN6DQoN/ !@#$%^&*()_+-={}|[]\\ :\" ;'<>?,./" ;
1011
+ let key = PublicKey :: parse ( key) . unwrap ( ) ;
1012
+ assert_eq ! ( key. comment. unwrap( ) , "!@#$%^&*()_+-={}|[]\\ :\" ;'<>?,./" ) ;
1013
+ }
1014
+
1015
+ #[ test]
1016
+ fn comment_should_preserve_multiple_spaces ( ) {
1017
+ let key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAhBr6++FQXB8kkgOMbdxBuyrHzuX5HkElswrN6DQoN/ comment with multiple spaces" ;
1018
+ let key = PublicKey :: parse ( key) . unwrap ( ) ;
1019
+ assert_eq ! ( key. comment. unwrap( ) , "comment with multiple spaces" ) ;
1020
+ }
1021
+
1022
+ #[ test]
1023
+ fn comment_should_remove_leading_and_trailing_spaces_while_keeping_body_intact ( ) {
1024
+ let key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAhBr6++FQXB8kkgOMbdxBuyrHzuX5HkElswrN6DQoN/ leading and trailing spaces are trimmed " ;
1025
+ let key = PublicKey :: parse ( key) . unwrap ( ) ;
1026
+ assert_eq ! (
1027
+ key. comment. unwrap( ) ,
1028
+ "leading and trailing spaces are trimmed"
1029
+ ) ;
1030
+ }
1031
+
1032
+ #[ test]
1033
+ fn comment_should_not_preserve_newlines ( ) {
1034
+ let key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAhBr6++FQXB8kkgOMbdxBuyrHzuX5HkElswrN6DQoN/ comment with\n newlines" ;
1035
+ let key = PublicKey :: parse ( key) ;
1036
+ assert ! ( key. is_err( ) ) ;
1037
+ }
1038
+
1039
+ #[ test]
1040
+ fn comment_should_preserve_mixed_whitespace ( ) {
1041
+ let key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAhBr6++FQXB8kkgOMbdxBuyrHzuX5HkElswrN6DQoN/ mixed white\t space" ;
1042
+ let key = PublicKey :: parse ( key) . unwrap ( ) ;
1043
+ assert_eq ! ( key. comment. unwrap( ) , "mixed white\t space" ) ;
1044
+ }
1045
+
1046
+ #[ test]
1047
+ fn comment_should_preserve_unicode_characters ( ) {
1048
+ let key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAhBr6++FQXB8kkgOMbdxBuyrHzuX5HkElswrN6DQoN/ comment with unicode: 中文, русский, عربى" ;
1049
+ let key = PublicKey :: parse ( key) . unwrap ( ) ;
1050
+ assert_eq ! (
1051
+ key. comment. unwrap( ) ,
1052
+ "comment with unicode: 中文, русский, عربى"
1053
+ ) ;
1054
+ }
986
1055
}
0 commit comments