28
28
//! }
29
29
//! }
30
30
31
- #[ macro_use]
32
- extern crate error_chain;
33
-
34
31
mod reader;
35
32
mod writer;
36
33
37
34
pub mod errors {
38
- error_chain ! {
39
- foreign_links {
40
- Utf8 ( :: std:: str :: Utf8Error ) ;
41
- }
42
- errors {
43
- InvalidFormat {
44
- description( "invalid key format" )
45
- display( "invalid key format" )
46
- }
47
- UnsupportedKeytype ( t: String ) {
48
- description( "unsupported keytype" )
49
- display( "unsupported keytype: {}" , t)
50
- }
51
- UnsupportedCurve ( t: String ) {
52
- description( "unsupported curve" )
53
- display( "unsupported curve: {}" , t)
54
- }
55
- }
35
+ use thiserror:: Error ;
36
+
37
+ pub type Result < T > = std:: result:: Result < T , OpenSSHKeyError > ;
38
+
39
+ #[ derive( Error , Debug ) ]
40
+ pub enum OpenSSHKeyError {
41
+ #[ error( "I/O error" ) ]
42
+ IO {
43
+ #[ from]
44
+ source : std:: io:: Error ,
45
+ } ,
46
+
47
+ #[ error( "invalid UTF-8" ) ]
48
+ InvalidUtf8 {
49
+ #[ from]
50
+ source : std:: str:: Utf8Error ,
51
+ } ,
52
+
53
+ // keep base64::DecodeError out of the public API
54
+ #[ error( "invalid base64: {detail}" ) ]
55
+ InvalidBase64 { detail : String } ,
56
+
57
+ #[ error( "invalid key format" ) ]
58
+ InvalidFormat ,
59
+
60
+ #[ error( "unsupported keytype: {keytype}" ) ]
61
+ UnsupportedKeyType { keytype : String } ,
62
+
63
+ #[ error( "unsupported curve: {curve}" ) ]
64
+ UnsupportedCurve { curve : String } ,
56
65
}
57
66
}
58
67
@@ -94,7 +103,11 @@ impl Curve {
94
103
NISTP_256 => Curve :: Nistp256 ,
95
104
NISTP_384 => Curve :: Nistp384 ,
96
105
NISTP_521 => Curve :: Nistp521 ,
97
- _ => return Err ( ErrorKind :: UnsupportedCurve ( curve. to_string ( ) ) . into ( ) ) ,
106
+ _ => {
107
+ return Err ( OpenSSHKeyError :: UnsupportedCurve {
108
+ curve : curve. to_string ( ) ,
109
+ } )
110
+ }
98
111
} )
99
112
}
100
113
@@ -161,7 +174,7 @@ impl core::cmp::PartialEq for PublicKey {
161
174
}
162
175
163
176
impl std:: str:: FromStr for PublicKey {
164
- type Err = Error ;
177
+ type Err = OpenSSHKeyError ;
165
178
fn from_str ( s : & str ) -> Result < Self > {
166
179
PublicKey :: parse ( s)
167
180
}
@@ -240,8 +253,8 @@ impl PublicKey {
240
253
fn try_key_parse ( key : & str ) -> Result < Self > {
241
254
// then parse the key according to rfc4253
242
255
let mut parts = key. split_whitespace ( ) ;
243
- let keytype = parts. next ( ) . ok_or ( ErrorKind :: InvalidFormat ) ?;
244
- let data = parts. next ( ) . ok_or ( ErrorKind :: InvalidFormat ) ?;
256
+ let keytype = parts. next ( ) . ok_or ( OpenSSHKeyError :: InvalidFormat ) ?;
257
+ let data = parts. next ( ) . ok_or ( OpenSSHKeyError :: InvalidFormat ) ?;
245
258
// comment is not required. if we get an empty comment (because of a
246
259
// trailing space) throw it out.
247
260
let comment = parts. next ( ) . and_then ( |c| {
@@ -252,11 +265,13 @@ impl PublicKey {
252
265
}
253
266
} ) ;
254
267
255
- let buf = base64:: decode ( data) . chain_err ( || ErrorKind :: InvalidFormat ) ?;
268
+ let buf = base64:: decode ( data) . map_err ( |e| OpenSSHKeyError :: InvalidBase64 {
269
+ detail : format ! ( "{}" , e) ,
270
+ } ) ?;
256
271
let mut reader = Reader :: new ( & buf) ;
257
272
let data_keytype = reader. read_string ( ) ?;
258
273
if keytype != data_keytype {
259
- return Err ( ErrorKind :: InvalidFormat . into ( ) ) ;
274
+ return Err ( OpenSSHKeyError :: InvalidFormat ) ;
260
275
}
261
276
262
277
let data = match keytype {
@@ -327,7 +342,11 @@ impl PublicKey {
327
342
key : key. into ( ) ,
328
343
}
329
344
}
330
- _ => return Err ( ErrorKind :: UnsupportedKeytype ( keytype. into ( ) ) . into ( ) ) ,
345
+ _ => {
346
+ return Err ( OpenSSHKeyError :: UnsupportedKeyType {
347
+ keytype : keytype. to_string ( ) ,
348
+ } )
349
+ }
331
350
} ;
332
351
333
352
Ok ( PublicKey {
@@ -348,10 +367,10 @@ impl PublicKey {
348
367
// authorized_keys files are newline-separated lists of public keys
349
368
let mut keys = vec ! [ ] ;
350
369
for key in keybuf. lines ( ) {
351
- let key = key. chain_err ( || "failed to read public key" ) ?;
370
+ let key = key?;
352
371
// skip any empty lines and any comment lines (prefixed with '#')
353
372
if !key. is_empty ( ) && !( key. trim ( ) . starts_with ( '#' ) ) {
354
- keys. push ( PublicKey :: parse ( & key) . chain_err ( || "failed to parse public key" ) ?) ;
373
+ keys. push ( PublicKey :: parse ( & key) ?) ;
355
374
}
356
375
}
357
376
Ok ( keys)
0 commit comments