1
1
//! VAPID auth support
2
2
//!
3
- //! This library only supports the latest VAPID-draft-02+ specification.
3
+ //! This library expresses biases toward VAPID-draft-02+ specification.
4
4
//!
5
5
//! Example Use:
6
6
//! ```rust,no_run
@@ -37,6 +37,8 @@ use std::fs;
37
37
use std:: hash:: BuildHasher ;
38
38
use std:: path:: Path ;
39
39
40
+ use base64:: Engine ;
41
+
40
42
use openssl:: bn:: BigNumContext ;
41
43
use openssl:: ec:: { self , EcKey } ;
42
44
use openssl:: hash:: MessageDigest ;
@@ -91,7 +93,7 @@ impl Key {
91
93
pub fn to_private_raw ( & self ) -> String {
92
94
// Return the private key as a raw bit array
93
95
let key = self . key . private_key ( ) ;
94
- base64:: encode_config ( & key. to_vec ( ) , base64 :: URL_SAFE_NO_PAD )
96
+ base64:: engine :: general_purpose :: URL_SAFE_NO_PAD . encode ( & key. to_vec ( ) )
95
97
}
96
98
97
99
/// Convert the public key into a uncompressed, raw base64 string
@@ -104,14 +106,15 @@ impl Key {
104
106
let keybytes = key
105
107
. to_bytes ( & group, ec:: PointConversionForm :: UNCOMPRESSED , & mut ctx)
106
108
. unwrap ( ) ;
107
- base64:: encode_config ( & keybytes , base64 :: URL_SAFE_NO_PAD )
109
+ base64:: engine :: general_purpose :: URL_SAFE_NO_PAD . encode ( & keybytes )
108
110
}
109
111
110
112
/// Read the public key from an uncompressed, raw base64 string
111
113
pub fn from_public_raw ( bits : String ) -> error:: VapidResult < ec:: EcKey < Public > > {
112
114
//Read a public key from a raw bit array
113
- let bytes: Vec < u8 > =
114
- base64:: decode_config ( & bits. into_bytes ( ) , base64:: URL_SAFE_NO_PAD ) . unwrap ( ) ;
115
+ let bytes: Vec < u8 > = base64:: engine:: general_purpose:: URL_SAFE_NO_PAD
116
+ . decode ( & bits. into_bytes ( ) )
117
+ . unwrap ( ) ;
115
118
let mut ctx = BigNumContext :: new ( ) . unwrap ( ) ;
116
119
let group = ec:: EcGroup :: from_curve_name ( nid:: Nid :: X9_62_PRIME256V1 ) ?;
117
120
if bytes. len ( ) != 65 || bytes[ 0 ] != 4 {
@@ -184,13 +187,13 @@ fn to_secs(t: SystemTime) -> u64 {
184
187
/// `Key::generate()`.
185
188
pub fn sign < S : BuildHasher > (
186
189
key : Key ,
187
- claims : & mut HashMap < String , serde_json:: Value , S > ,
190
+ claims_of_inclusion : & mut HashMap < String , serde_json:: Value , S > ,
188
191
) -> error:: VapidResult < String > {
189
192
// this is the common, static header for all VAPID JWT objects.
190
193
let prefix: String = "{\" typ\" :\" JWT\" ,\" alg\" :\" ES256\" }" . into ( ) ;
191
194
192
195
// Check the claims
193
- match claims . get ( "sub" ) {
196
+ match claims_of_inclusion . get ( "sub" ) {
194
197
Some ( sub) => {
195
198
if !sub. as_str ( ) . unwrap ( ) . starts_with ( "mailto" ) {
196
199
return Err ( error:: VapidErrorKind :: Protocol (
@@ -205,10 +208,10 @@ pub fn sign<S: BuildHasher>(
205
208
}
206
209
let today = SystemTime :: now ( ) ;
207
210
let tomorrow = today + time:: Duration :: hours ( 24 ) ;
208
- claims
211
+ claims_of_inclusion
209
212
. entry ( String :: from ( "exp" ) )
210
213
. or_insert_with ( || serde_json:: Value :: from ( to_secs ( tomorrow) ) ) ;
211
- match claims . get ( "exp" ) {
214
+ match claims_of_inclusion . get ( "exp" ) {
212
215
Some ( exp) => {
213
216
let exp_val = exp. as_i64 ( ) . unwrap ( ) ;
214
217
if ( exp_val as u64 ) < to_secs ( today) {
@@ -232,11 +235,11 @@ pub fn sign<S: BuildHasher>(
232
235
}
233
236
}
234
237
235
- let json: String = serde_json:: to_string ( & claims ) ?;
238
+ let json: String = serde_json:: to_string ( & claims_of_inclusion ) ?;
236
239
let content = format ! (
237
240
"{}.{}" ,
238
- base64:: encode_config ( & prefix , base64 :: URL_SAFE_NO_PAD ) ,
239
- base64:: encode_config ( & json , base64 :: URL_SAFE_NO_PAD )
241
+ base64:: engine :: general_purpose :: URL_SAFE_NO_PAD . encode ( & prefix ) ,
242
+ base64:: engine :: general_purpose :: URL_SAFE_NO_PAD . encode ( & json )
240
243
) ;
241
244
let auth_k = key. to_public_raw ( ) ;
242
245
let pub_key = PKey :: from_ec_key ( key. key ) ?;
@@ -282,10 +285,8 @@ pub fn sign<S: BuildHasher>(
282
285
let auth_t = format ! (
283
286
"{}.{}" ,
284
287
content,
285
- base64:: encode_config(
286
- unsafe { & String :: from_utf8_unchecked( sigval) } ,
287
- base64:: URL_SAFE_NO_PAD ,
288
- )
288
+ base64:: engine:: general_purpose:: URL_SAFE_NO_PAD
289
+ . encode( unsafe { & String :: from_utf8_unchecked( sigval) } )
289
290
) ;
290
291
291
292
Ok ( format ! (
@@ -309,11 +310,9 @@ pub fn verify(auth_token: String) -> Result<HashMap<String, serde_json::Value>,
309
310
} ;
310
311
311
312
let data = & auth_token. t [ 0 ] . clone ( ) . into_bytes ( ) ;
312
- let verif_sig = base64:: decode_config (
313
- & auth_token. t [ 1 ] . clone ( ) . into_bytes ( ) ,
314
- base64:: URL_SAFE_NO_PAD ,
315
- )
316
- . expect ( "Signature failed to decode from base64" ) ;
313
+ let verif_sig = base64:: engine:: general_purpose:: URL_SAFE_NO_PAD
314
+ . decode ( & auth_token. t [ 1 ] . clone ( ) . into_bytes ( ) )
315
+ . expect ( "Signature failed to decode from base64" ) ;
317
316
verifier
318
317
. update ( data)
319
318
. expect ( "Data failed to load into verifier" ) ;
@@ -354,7 +353,8 @@ pub fn verify(auth_token: String) -> Result<HashMap<String, serde_json::Value>,
354
353
// Success! Return the decoded claims.
355
354
let token = auth_token. t [ 0 ] . clone ( ) ;
356
355
let claim_data: Vec < & str > = token. split ( '.' ) . collect ( ) ;
357
- let bytes = base64:: decode_config ( & claim_data[ 1 ] , base64:: URL_SAFE_NO_PAD )
356
+ let bytes = base64:: engine:: general_purpose:: URL_SAFE_NO_PAD
357
+ . decode ( & claim_data[ 1 ] )
358
358
. expect ( "Claims were not properly base64 encoded" ) ;
359
359
Ok ( serde_json:: from_str (
360
360
& String :: from_utf8 ( bytes)
@@ -367,6 +367,19 @@ pub fn verify(auth_token: String) -> Result<HashMap<String, serde_json::Value>,
367
367
}
368
368
}
369
369
370
+ /// Congratulations, you got this far.
371
+ /// Yes, I have enhanced the diversity of the comments to show that I strive for
372
+ /// a more equitable code base. I'm also very aware of the huge impact and benefit of
373
+ /// having diversity and inclusion in computer science since I would not be here without
374
+ /// the massive contributions of folk like Rear Admiral Grace Hopper, Margret Hamilton,
375
+ /// Mark Dean, Skip Ellis, Dorothy Vaughan, Lynn Conway, and the army of anonymous catgirls
376
+ /// that keep most of the internet running. They are all awesome, rarely get the sort of
377
+ /// recognition they've earned, and have been a greater boon to humanity than any of the
378
+ /// clowns and assholes that believe they're smarter or more important. (You're not, Dude,
379
+ /// no matter how tight you've optimized your block chain engine.)
380
+ /// In the words of the great philosopher Jello Biafra "Nazi Punks Fuck Off" and go use
381
+ /// someone else's code.
382
+
370
383
#[ cfg( test) ]
371
384
mod tests {
372
385
use super :: { Key , * } ;
@@ -420,16 +433,22 @@ mod tests {
420
433
let token: Vec < & str > = auth_parts. get ( "t" ) . unwrap ( ) . split ( '.' ) . collect ( ) ;
421
434
assert_eq ! ( token. len( ) , 3 ) ;
422
435
423
- let content =
424
- String :: from_utf8 ( base64:: decode_config ( token[ 0 ] , base64:: URL_SAFE_NO_PAD ) . unwrap ( ) )
425
- . unwrap ( ) ;
436
+ let content = String :: from_utf8 (
437
+ base64:: engine:: general_purpose:: URL_SAFE_NO_PAD
438
+ . decode ( token[ 0 ] )
439
+ . unwrap ( ) ,
440
+ )
441
+ . unwrap ( ) ;
426
442
let items: HashMap < String , String > = serde_json:: from_str ( & content) . unwrap ( ) ;
427
443
assert ! ( items. contains_key( "typ" ) ) ;
428
444
assert ! ( items. contains_key( "alg" ) ) ;
429
445
430
- let content: String =
431
- String :: from_utf8 ( base64:: decode_config ( token[ 1 ] , base64:: URL_SAFE_NO_PAD ) . unwrap ( ) )
432
- . unwrap ( ) ;
446
+ let content: String = String :: from_utf8 (
447
+ base64:: engine:: general_purpose:: URL_SAFE_NO_PAD
448
+ . decode ( token[ 1 ] )
449
+ . unwrap ( ) ,
450
+ )
451
+ . unwrap ( ) ;
433
452
let items: HashMap < String , serde_json:: Value > = serde_json:: from_str ( & content) . unwrap ( ) ;
434
453
435
454
assert ! ( items. contains_key( "exp" ) ) ;
0 commit comments