char/avril
(wip) why'd you have to go and make things so complicaaaaated?
git clone https://git.t4t.associates/char/avril
f4a0f5b
main
1use std:: io; 2 3use ed25519_dalek:: Signer as _; 4use p256:: elliptic_curve:: sec1:: ToEncodedPoint ; 5use pkcs8::{ DecodePrivateKey , DecodePublicKey , EncodePrivateKey , EncodePublicKey }; 6use rand:: RngCore ; 7use rand:: rngs:: OsRng ; 8use rsa::{ 9RsaPrivateKey , RsaPublicKey , 10 hazmat::{ rsa_decrypt_and_checkas rsa_decrypt_raw, rsa_encryptas rsa_encrypt_raw}, 11 traits::{ PrivateKeyParts , PublicKeyParts }, 12}; 13use sha2:: Digest as _; 14use signature:: Verifier ; 15use subtle:: ConstantTimeEq as _; 16use zeroize::{ Zeroize , Zeroizing }; 17 18pub ( crate ) struct KeyPairDer { 19pub private : Zeroizing < Vec < u8 >>, 20pub public : Vec < u8 >, 21pub length : usize , 22pub exponent : Vec < u8 >, 23} 24 25fn unsupported () -> io:: Error { 26 io:: Error :: other ( "Unsupported asymmetric crypto operation" ) 27} 28 29fn hash_bytes ( name : & str , data : & [ u8 ]) -> io:: Result < Vec < u8 >> { 30match name{ 31"SHA-1" =>Ok ( sha1:: Sha1 :: digest ( data). to_vec ()), 32"SHA-256" =>Ok ( sha2:: Sha256 :: digest ( data). to_vec ()), 33"SHA-384" =>Ok ( sha2:: Sha384 :: digest ( data). to_vec ()), 34"SHA-512" =>Ok ( sha2:: Sha512 :: digest ( data). to_vec ()), 35 _ =>Err ( unsupported ()), 36} 37} 38 39pub ( crate ) fn generate ( 40name : & str , 41length : usize , 42exponent : & [ u8 ], 43curve : & str , 44) -> io:: Result < KeyPairDer > { 45let mut rng =OsRng ; 46match name{ 47"RSA-OAEP" |"RSA-PSS" |"RSASSA-PKCS1-V1_5" =>{ 48if !( 512 ..=8192 ). contains ( & length) || !length. is_multiple_of ( 8 ) || exponent. is_empty () { 49return Err ( io:: Error :: other ( "Invalid RSA key parameters" )); 50} 51let exp = rsa:: BigUint :: from_bytes_be ( exponent); 52let exponent_bytes = exp. to_bytes_be (); 53if exp < rsa:: BigUint :: from ( 3u8 ) 54 || exponent_bytes. last (). is_none_or ( |byte| byte %2 ==0 ) 55{ 56return Err ( io:: Error :: other ( "Invalid RSA public exponent" )); 57} 58let private = 59RsaPrivateKey :: new_with_exp ( & mut rng, length, & exp). map_err ( io:: Error :: other) ?; 60let public =RsaPublicKey :: from ( & private); 61let private_der = private. to_pkcs8_der (). map_err ( io:: Error :: other) ?; 62let public_der = public. to_public_key_der (). map_err ( io:: Error :: other) ?; 63Ok ( KeyPairDer { 64private : Zeroizing :: new ( private_der. as_bytes (). to_vec ()), 65public : public_der. as_bytes (). to_vec (), 66 length, 67exponent : exp. to_bytes_be (), 68}) 69} 70"ECDSA" |"ECDH" =>match curve{ 71"P-256" =>{ 72let private = p256:: SecretKey :: random ( & mut rng); 73let public = private. public_key (); 74Ok ( KeyPairDer { 75private : Zeroizing :: new ( 76 private 77. to_pkcs8_der () 78. map_err ( io:: Error :: other) ? 79. as_bytes () 80. to_vec (), 81), 82public : public 83. to_public_key_der () 84. map_err ( io:: Error :: other) ? 85. as_bytes () 86. to_vec (), 87length : 256 , 88exponent : Vec :: new (), 89}) 90} 91"P-384" =>{ 92let private = p384:: SecretKey :: random ( & mut rng); 93let public = private. public_key (); 94Ok ( KeyPairDer { 95private : Zeroizing :: new ( 96 private 97. to_pkcs8_der () 98. map_err ( io:: Error :: other) ? 99. as_bytes () 100. to_vec (), 101), 102public : public 103. to_public_key_der () 104. map_err ( io:: Error :: other) ? 105. as_bytes () 106. to_vec (), 107length : 384 , 108exponent : Vec :: new (), 109}) 110} 111"P-521" =>{ 112let private = p521:: SecretKey :: random ( & mut rng); 113let public = private. public_key (); 114Ok ( KeyPairDer { 115private : Zeroizing :: new ( 116 private 117. to_pkcs8_der () 118. map_err ( io:: Error :: other) ? 119. as_bytes () 120. to_vec (), 121), 122public : public 123. to_public_key_der () 124. map_err ( io:: Error :: other) ? 125. as_bytes () 126. to_vec (), 127length : 521 , 128exponent : Vec :: new (), 129}) 130} 131 _ =>Err ( unsupported ()), 132}, 133"ED25519" =>{ 134let private = ed25519_dalek:: SigningKey :: generate ( & mut rng); 135let public = private. verifying_key (); 136Ok ( KeyPairDer { 137private : Zeroizing :: new ( 138 private 139. to_pkcs8_der () 140. map_err ( io:: Error :: other) ? 141. as_bytes () 142. to_vec (), 143), 144public : public 145. to_public_key_der () 146. map_err ( io:: Error :: other) ? 147. as_bytes () 148. to_vec (), 149length : 256 , 150exponent : Vec :: new (), 151}) 152} 153"X25519" =>{ 154let mut secret =[ 0u8 ; 32 ]; 155 rng. fill_bytes ( & mut secret); 156let private = x25519_dalek:: StaticSecret :: from ( secret); 157 secret. zeroize (); 158let public = x25519_dalek:: PublicKey :: from ( & private); 159let private_der =Zeroizing :: new ( private. to_bytes (). to_vec ()); 160Ok ( KeyPairDer { 161private : private_der, 162public : public. to_bytes (). to_vec (), 163length : 256 , 164exponent : Vec :: new (), 165}) 166} 167 _ =>Err ( unsupported ()), 168} 169} 170 171pub ( crate ) struct ImportedKey { 172pub bytes : Vec < u8 >, 173pub length : usize , 174pub exponent : Vec < u8 >, 175pub curve : String , 176} 177 178fn x25519_der ( private : bool , key : & [ u8 ]) -> io:: Result < Vec < u8 >> { 179let prefix: & [ u8 ] =if private{ 180& [ 1810x30 , 0x2e , 0x02 , 0x01 , 0x00 , 0x30 , 0x05 , 0x06 , 0x03 , 0x2b , 0x65 , 0x6e , 0x04 , 0x22 , 1820x04 , 0x20 , 183] 184} else { 185& [ 1860x30 , 0x2a , 0x30 , 0x05 , 0x06 , 0x03 , 0x2b , 0x65 , 0x6e , 0x03 , 0x21 , 0x00 , 187] 188}; 189if key. len () !=32 { 190return Err ( unsupported ()); 191} 192let mut der = prefix. to_vec (); 193 der. extend_from_slice ( key); 194Ok ( der) 195} 196 197fn x25519_from_der ( private : bool , der : & [ u8 ]) -> io:: Result < Vec < u8 >> { 198let prefix: & [ u8 ] =if private{ 199& [ 2000x30 , 0x2e , 0x02 , 0x01 , 0x00 , 0x30 , 0x05 , 0x06 , 0x03 , 0x2b , 0x65 , 0x6e , 0x04 , 0x22 , 2010x04 , 0x20 , 202] 203} else { 204& [ 2050x30 , 0x2a , 0x30 , 0x05 , 0x06 , 0x03 , 0x2b , 0x65 , 0x6e , 0x03 , 0x21 , 0x00 , 206] 207}; 208if der. len () != prefix. len () +32 || !der. starts_with ( prefix) { 209return Err ( unsupported ()); 210} 211Ok ( der[ prefix. len () ..]. to_vec ()) 212} 213 214fn ec_public_sec1 ( der : & [ u8 ]) -> io:: Result < Vec < u8 >> { 215let info = pkcs8:: spki:: SubjectPublicKeyInfoRef :: try_from ( der). map_err ( io:: Error :: other) ?; 216 info. subject_public_key 217. as_bytes () 218. map ( ToOwned :: to_owned) 219. ok_or_else ( unsupported) 220} 221 222pub ( crate ) fn import_key ( 223format : & str , 224data : & [ u8 ], 225name : & str , 226curve : & str , 227) -> io:: Result < ImportedKey > { 228let private = format =="pkcs8" ; 229if format =="raw" && private{ 230return Err ( unsupported ()); 231} 232if !matches! ( format, "raw" |"spki" |"pkcs8" ) { 233return Err ( unsupported ()); 234} 235match name{ 236"RSA-OAEP" |"RSA-PSS" |"RSASSA-PKCS1-V1_5" =>{ 237let ( bytes, length, exponent) =if private{ 238let key =RsaPrivateKey :: from_pkcs8_der ( data). map_err ( io:: Error :: other) ?; 239if !( 512 ..=8192 ). contains ( & key. n (). bits ()) { 240return Err ( io:: Error :: other ( "Invalid RSA modulus size" )); 241} 242let bytes = key 243. to_pkcs8_der () 244. map_err ( io:: Error :: other) ? 245. as_bytes () 246. to_vec (); 247( bytes, key. n (). bits (), key. e (). to_bytes_be ()) 248} else { 249let key =RsaPublicKey :: from_public_key_der ( data). map_err ( io:: Error :: other) ?; 250if !( 512 ..=8192 ). contains ( & key. n (). bits ()) { 251return Err ( io:: Error :: other ( "Invalid RSA modulus size" )); 252} 253let bytes = key 254. to_public_key_der () 255. map_err ( io:: Error :: other) ? 256. as_bytes () 257. to_vec (); 258( bytes, key. n (). bits (), key. e (). to_bytes_be ()) 259}; 260Ok ( ImportedKey { 261 bytes, 262 length, 263 exponent, 264curve : String :: new (), 265}) 266} 267"ECDSA" |"ECDH" =>match ( curve, format) { 268( "P-256" , "raw" ) =>{ 269let key = p256:: PublicKey :: from_sec1_bytes ( data). map_err ( io:: Error :: other) ?; 270Ok ( ImportedKey { 271bytes : key 272. to_public_key_der () 273. map_err ( io:: Error :: other) ? 274. as_bytes () 275. to_vec (), 276length : 256 , 277exponent : Vec :: new (), 278curve : curve. into (), 279}) 280} 281( "P-256" , "pkcs8" ) =>{ 282let key = p256:: SecretKey :: from_pkcs8_der ( data). map_err ( io:: Error :: other) ?; 283Ok ( ImportedKey { 284bytes : key 285. to_pkcs8_der () 286. map_err ( io:: Error :: other) ? 287. as_bytes () 288. to_vec (), 289length : 256 , 290exponent : Vec :: new (), 291curve : curve. into (), 292}) 293} 294( "P-256" , "spki" ) =>{ 295let key = p256:: PublicKey :: from_public_key_der ( data). map_err ( io:: Error :: other) ?; 296Ok ( ImportedKey { 297bytes : key 298. to_public_key_der () 299. map_err ( io:: Error :: other) ? 300. as_bytes () 301. to_vec (), 302length : 256 , 303exponent : Vec :: new (), 304curve : curve. into (), 305}) 306} 307( "P-384" , "raw" ) =>{ 308let key = p384:: PublicKey :: from_sec1_bytes ( data). map_err ( io:: Error :: other) ?; 309Ok ( ImportedKey { 310bytes : key 311. to_public_key_der () 312. map_err ( io:: Error :: other) ? 313. as_bytes () 314. to_vec (), 315length : 384 , 316exponent : Vec :: new (), 317curve : curve. into (), 318}) 319} 320( "P-384" , "pkcs8" ) =>{ 321let key = p384:: SecretKey :: from_pkcs8_der ( data). map_err ( io:: Error :: other) ?; 322Ok ( ImportedKey { 323bytes : key 324. to_pkcs8_der () 325. map_err ( io:: Error :: other) ? 326. as_bytes () 327. to_vec (), 328length : 384 , 329exponent : Vec :: new (), 330curve : curve. into (), 331}) 332} 333( "P-384" , "spki" ) =>{ 334let key = p384:: PublicKey :: from_public_key_der ( data). map_err ( io:: Error :: other) ?; 335Ok ( ImportedKey { 336bytes : key 337. to_public_key_der () 338. map_err ( io:: Error :: other) ? 339. as_bytes () 340. to_vec (), 341length : 384 , 342exponent : Vec :: new (), 343curve : curve. into (), 344}) 345} 346( "P-521" , "raw" ) =>{ 347let key = p521:: PublicKey :: from_sec1_bytes ( data). map_err ( io:: Error :: other) ?; 348Ok ( ImportedKey { 349bytes : key 350. to_public_key_der () 351. map_err ( io:: Error :: other) ? 352. as_bytes () 353. to_vec (), 354length : 521 , 355exponent : Vec :: new (), 356curve : curve. into (), 357}) 358} 359( "P-521" , "pkcs8" ) =>{ 360let key = p521:: SecretKey :: from_pkcs8_der ( data). map_err ( io:: Error :: other) ?; 361Ok ( ImportedKey { 362bytes : key 363. to_pkcs8_der () 364. map_err ( io:: Error :: other) ? 365. as_bytes () 366. to_vec (), 367length : 521 , 368exponent : Vec :: new (), 369curve : curve. into (), 370}) 371} 372( "P-521" , "spki" ) =>{ 373let sec1 =ec_public_sec1 ( data) ?; 374let key = p521:: PublicKey :: from_sec1_bytes ( & sec1). map_err ( io:: Error :: other) ?; 375Ok ( ImportedKey { 376bytes : key 377. to_public_key_der () 378. map_err ( io:: Error :: other) ? 379. as_bytes () 380. to_vec (), 381length : 521 , 382exponent : Vec :: new (), 383curve : curve. into (), 384}) 385} 386 _ =>Err ( unsupported ()), 387}, 388"ED25519" =>match format{ 389"raw" =>{ 390let public: [ u8 ; 32 ] = data 391. try_into () 392. map_err ( |_| io:: Error :: other ( "Invalid key length" )) ?; 393let key = 394 ed25519_dalek:: VerifyingKey :: from_bytes ( & public). map_err ( io:: Error :: other) ?; 395Ok ( ImportedKey { 396bytes : key 397. to_public_key_der () 398. map_err ( io:: Error :: other) ? 399. as_bytes () 400. to_vec (), 401length : 256 , 402exponent : Vec :: new (), 403curve : String :: new (), 404}) 405} 406"spki" =>{ 407let key = ed25519_dalek:: VerifyingKey :: from_public_key_der ( data) 408. map_err ( io:: Error :: other) ?; 409Ok ( ImportedKey { 410bytes : key 411. to_public_key_der () 412. map_err ( io:: Error :: other) ? 413. as_bytes () 414. to_vec (), 415length : 256 , 416exponent : Vec :: new (), 417curve : String :: new (), 418}) 419} 420"pkcs8" =>{ 421let key = 422 ed25519_dalek:: SigningKey :: from_pkcs8_der ( data). map_err ( io:: Error :: other) ?; 423Ok ( ImportedKey { 424bytes : key 425. to_pkcs8_der () 426. map_err ( io:: Error :: other) ? 427. as_bytes () 428. to_vec (), 429length : 256 , 430exponent : Vec :: new (), 431curve : String :: new (), 432}) 433} 434 _ =>Err ( unsupported ()), 435}, 436"X25519" =>{ 437let bytes =match format{ 438"raw" |"spki" if !private =>{ 439if format =="raw" { 440 data. to_vec () 441} else { 442x25519_from_der ( false , data) ? 443} 444} 445"pkcs8" if private =>x25519_from_der ( true , data) ?, 446 _ =>return Err ( unsupported ()), 447}; 448if bytes. len () !=32 { 449return Err ( unsupported ()); 450} 451Ok ( ImportedKey { 452 bytes, 453length : 256 , 454exponent : Vec :: new (), 455curve : String :: new (), 456}) 457} 458 _ =>Err ( unsupported ()), 459} 460} 461 462pub ( crate ) fn export_key ( 463format : & str , 464data : & [ u8 ], 465name : & str , 466key_type : & str , 467curve : & str , 468) -> io:: Result < Vec < u8 >> { 469if ( format =="raw" && key_type =="private" ) 470 ||( format =="pkcs8" && key_type !="private" ) 471 ||( format =="spki" && key_type !="public" ) 472{ 473return Err ( io:: Error :: other ( 474"InvalidAccessError: key type is incompatible with key format" , 475)); 476} 477match ( format, name, key_type) { 478( 479"pkcs8" , 480"RSA-OAEP" |"RSA-PSS" |"RSASSA-PKCS1-V1_5" |"ECDSA" |"ECDH" |"ED25519" , 481"private" , 482) =>Ok ( data. to_vec ()), 483( 484"spki" , 485"RSA-OAEP" |"RSA-PSS" |"RSASSA-PKCS1-V1_5" |"ECDSA" |"ECDH" |"ED25519" , 486"public" , 487) =>Ok ( data. to_vec ()), 488( "raw" , "ECDSA" |"ECDH" , "public" ) =>match curve{ 489"P-256" =>Ok ( p256:: PublicKey :: from_public_key_der ( data) 490. map_err ( io:: Error :: other) ? 491. to_encoded_point ( false ) 492. as_bytes () 493. to_vec ()), 494"P-384" =>Ok ( p384:: PublicKey :: from_public_key_der ( data) 495. map_err ( io:: Error :: other) ? 496. to_encoded_point ( false ) 497. as_bytes () 498. to_vec ()), 499"P-521" =>Ok ( ec_public_sec1 ( data) ?), 500 _ =>Err ( unsupported ()), 501}, 502( "raw" , "ED25519" , "public" ) =>Ok ( ed25519_dalek:: VerifyingKey :: from_public_key_der ( data) 503. map_err ( io:: Error :: other) ? 504. to_bytes () 505. to_vec ()), 506( "raw" , "X25519" , "public" ) =>Ok ( data. to_vec ()), 507( "spki" , "X25519" , "public" ) =>x25519_der ( false , data), 508( "pkcs8" , "X25519" , "private" ) =>x25519_der ( true , data), 509 _ =>Err ( unsupported ()), 510} 511} 512 513fn jwk_bytes ( value : & serde_json:: Value , field : & str ) -> io:: Result < Vec < u8 >> { 514use base64:: Engine ; 515use base64:: engine:: general_purpose:: URL_SAFE_NO_PAD ; 516let encoded = value 517. get ( field) 518. and_then ( serde_json:: Value :: as_str) 519. ok_or_else ( || io:: Error :: other ( "JWK field is missing" )) ?; 520URL_SAFE_NO_PAD . decode ( encoded). map_err ( io:: Error :: other) 521} 522 523fn b64 ( bytes : & [ u8 ]) ->String { 524use base64:: Engine ; 525use base64:: engine:: general_purpose:: URL_SAFE_NO_PAD ; 526URL_SAFE_NO_PAD . encode ( bytes) 527} 528 529pub ( crate ) fn import_jwk ( 530jwk : & serde_json:: Value , 531name : & str , 532hash : & str , 533curve : & str , 534) -> io:: Result <( ImportedKey , String )> { 535match name{ 536"RSA-OAEP" |"RSA-PSS" |"RSASSA-PKCS1-V1_5" =>{ 537if jwk. get ( "kty" ). and_then ( serde_json:: Value :: as_str) !=Some ( "RSA" ) { 538return Err ( io:: Error :: other ( "JWK kty does not match RSA" )); 539} 540if jwk. get ( "oth" ). is_some () { 541return Err ( io:: Error :: other ( "Multiprime RSA JWKs are unsupported" )); 542} 543let n_bytes =jwk_bytes ( jwk, "n" ) ?; 544let e_bytes =jwk_bytes ( jwk, "e" ) ?; 545if n_bytes. is_empty () || e_bytes. is_empty () || n_bytes[ 0 ] ==0 || e_bytes[ 0 ] ==0 { 546return Err ( io:: Error :: other ( "Invalid RSA JWK integer encoding" )); 547} 548let n = rsa:: BigUint :: from_bytes_be ( & n_bytes); 549if n. bits () <512 || n. bits () >8192 { 550return Err ( io:: Error :: other ( "Invalid RSA modulus size" )); 551} 552let e = rsa:: BigUint :: from_bytes_be ( & e_bytes); 553let private = jwk. get ( "d" ). is_some (); 554let ( bytes, length) =if private{ 555let d = rsa:: BigUint :: from_bytes_be ( & jwk_bytes ( jwk, "d" ) ?); 556let p = rsa:: BigUint :: from_bytes_be ( & jwk_bytes ( jwk, "p" ) ?); 557let q = rsa:: BigUint :: from_bytes_be ( & jwk_bytes ( jwk, "q" ) ?); 558let dp = rsa:: BigUint :: from_bytes_be ( & jwk_bytes ( jwk, "dp" ) ?); 559let dq = rsa:: BigUint :: from_bytes_be ( & jwk_bytes ( jwk, "dq" ) ?); 560let qi = rsa:: BigUint :: from_bytes_be ( & jwk_bytes ( jwk, "qi" ) ?); 561let mut key =RsaPrivateKey :: from_components ( n, e, d, vec! [ p, q]) 562. map_err ( io:: Error :: other) ?; 563 key. precompute (). map_err ( io:: Error :: other) ?; 564 key. validate (). map_err ( io:: Error :: other) ?; 565if key. dp () !=Some ( & dp) 566 || key. dq () !=Some ( & dq) 567 || key. qinv (). and_then ( |v| v. to_biguint ()). as_ref () !=Some ( & qi) 568{ 569return Err ( io:: Error :: other ( "JWK RSA CRT parameters do not match" )); 570} 571let length = key. n (). bits (); 572( 573 key. to_pkcs8_der () 574. map_err ( io:: Error :: other) ? 575. as_bytes () 576. to_vec (), 577 length, 578) 579} else { 580let key =RsaPublicKey :: new ( n, e). map_err ( io:: Error :: other) ?; 581let length = key. n (). bits (); 582( 583 key. to_public_key_der () 584. map_err ( io:: Error :: other) ? 585. as_bytes () 586. to_vec (), 587 length, 588) 589}; 590let expected_alg =match name{ 591"RSA-OAEP" =>{ 592if hash =="SHA-1" { 593"RSA-OAEP" . to_owned () 594} else { 595format! ( "RSA-OAEP-{}" , & hash[ 4 ..]) 596} 597} 598"RSA-PSS" =>format! ( "PS{}" , & hash[ 4 ..]), 599 _ =>format! ( "RS{}" , & hash[ 4 ..]), 600}; 601if let Some ( alg) = jwk. get ( "alg" ) 602 && alg. as_str () !=Some ( expected_alg. as_str ()) 603{ 604return Err ( io:: Error :: other ( "JWK alg does not match RSA hash" )); 605} 606Ok (( 607ImportedKey { 608 bytes, 609 length, 610exponent : e_bytes, 611curve : String :: new (), 612}, 613if private{ "private" } else { "public" }. into (), 614)) 615} 616"ECDSA" |"ECDH" =>{ 617if jwk. get ( "kty" ). and_then ( serde_json:: Value :: as_str) !=Some ( "EC" ) { 618return Err ( io:: Error :: other ( "JWK kty does not match EC" )); 619} 620let expected_curve =match curve{ 621"P-256" =>"P-256" , 622"P-384" =>"P-384" , 623"P-521" =>"P-521" , 624 _ =>return Err ( unsupported ()), 625}; 626if jwk. get ( "crv" ). and_then ( serde_json:: Value :: as_str) !=Some ( expected_curve) { 627return Err ( io:: Error :: other ( "JWK curve does not match" )); 628} 629let x =jwk_bytes ( jwk, "x" ) ?; 630let y =jwk_bytes ( jwk, "y" ) ?; 631let width =match curve{ 632"P-256" =>32 , 633"P-384" =>48 , 634"P-521" =>66 , 635 _ =>return Err ( unsupported ()), 636}; 637if x. len () != width || y. len () != width{ 638return Err ( io:: Error :: other ( "Invalid EC JWK coordinate length" )); 639} 640let private = jwk. get ( "d" ). is_some (); 641if private &&jwk_bytes ( jwk, "d" ) ?. len () != width{ 642return Err ( io:: Error :: other ( "Invalid EC JWK private key length" )); 643} 644let mut point =Vec :: with_capacity ( 1 + x. len () + y. len ()); 645 point. push ( 4 ); 646 point. extend_from_slice ( & x); 647 point. extend_from_slice ( & y); 648let ( bytes, length) =match ( curve, private) { 649( "P-256" , true ) =>{ 650let key = p256:: SecretKey :: from_slice ( & jwk_bytes ( jwk, "d" ) ?) 651. map_err ( io:: Error :: other) ?; 652if key. public_key (). to_encoded_point ( false ). as_bytes () != point{ 653return Err ( io:: Error :: other ( 654"JWK EC public and private values disagree" , 655)); 656} 657( 658 key. to_pkcs8_der () 659. map_err ( io:: Error :: other) ? 660. as_bytes () 661. to_vec (), 662256 , 663) 664} 665( "P-256" , false ) =>( 666 p256:: PublicKey :: from_sec1_bytes ( & point) 667. map_err ( io:: Error :: other) ? 668. to_public_key_der () 669. map_err ( io:: Error :: other) ? 670. as_bytes () 671. to_vec (), 672256 , 673), 674( "P-384" , true ) =>{ 675let key = p384:: SecretKey :: from_slice ( & jwk_bytes ( jwk, "d" ) ?) 676. map_err ( io:: Error :: other) ?; 677if key. public_key (). to_encoded_point ( false ). as_bytes () != point{ 678return Err ( io:: Error :: other ( 679"JWK EC public and private values disagree" , 680)); 681} 682( 683 key. to_pkcs8_der () 684. map_err ( io:: Error :: other) ? 685. as_bytes () 686. to_vec (), 687384 , 688) 689} 690( "P-384" , false ) =>( 691 p384:: PublicKey :: from_sec1_bytes ( & point) 692. map_err ( io:: Error :: other) ? 693. to_public_key_der () 694. map_err ( io:: Error :: other) ? 695. as_bytes () 696. to_vec (), 697384 , 698), 699( "P-521" , true ) =>{ 700let key = p521:: SecretKey :: from_slice ( & jwk_bytes ( jwk, "d" ) ?) 701. map_err ( io:: Error :: other) ?; 702if key. public_key (). to_encoded_point ( false ). as_bytes () != point{ 703return Err ( io:: Error :: other ( 704"JWK EC public and private values disagree" , 705)); 706} 707( 708 key. to_pkcs8_der () 709. map_err ( io:: Error :: other) ? 710. as_bytes () 711. to_vec (), 712521 , 713) 714} 715( "P-521" , false ) =>( 716 p521:: PublicKey :: from_sec1_bytes ( & point) 717. map_err ( io:: Error :: other) ? 718. to_public_key_der () 719. map_err ( io:: Error :: other) ? 720. as_bytes () 721. to_vec (), 722521 , 723), 724 _ =>return Err ( unsupported ()), 725}; 726Ok (( 727ImportedKey { 728 bytes, 729 length, 730exponent : Vec :: new (), 731curve : curve. into (), 732}, 733if private{ "private" } else { "public" }. into (), 734)) 735} 736"ED25519" =>{ 737if jwk. get ( "kty" ). and_then ( serde_json:: Value :: as_str) !=Some ( "OKP" ) 738 || jwk. get ( "crv" ). and_then ( serde_json:: Value :: as_str) !=Some ( "Ed25519" ) 739{ 740return Err ( io:: Error :: other ( "JWK is not Ed25519" )); 741} 742let x: [ u8 ; 32 ] =jwk_bytes ( jwk, "x" ) ? 743. try_into () 744. map_err ( |_| io:: Error :: other ( "Invalid key length" )) ?; 745let private = jwk. get ( "d" ). is_some (); 746let bytes =if private{ 747let d: [ u8 ; 32 ] =jwk_bytes ( jwk, "d" ) ? 748. try_into () 749. map_err ( |_| io:: Error :: other ( "Invalid key length" )) ?; 750let key = ed25519_dalek:: SigningKey :: from_bytes ( & d); 751if key. verifying_key (). to_bytes () != x{ 752return Err ( io:: Error :: other ( "JWK public and private values disagree" )); 753} 754 key. to_pkcs8_der () 755. map_err ( io:: Error :: other) ? 756. as_bytes () 757. to_vec () 758} else { 759 ed25519_dalek:: VerifyingKey :: from_bytes ( & x) 760. map_err ( io:: Error :: other) ? 761. to_public_key_der () 762. map_err ( io:: Error :: other) ? 763. as_bytes () 764. to_vec () 765}; 766Ok (( 767ImportedKey { 768 bytes, 769length : 256 , 770exponent : Vec :: new (), 771curve : String :: new (), 772}, 773if private{ "private" } else { "public" }. into (), 774)) 775} 776"X25519" =>{ 777if jwk. get ( "kty" ). and_then ( serde_json:: Value :: as_str) !=Some ( "OKP" ) 778 || jwk. get ( "crv" ). and_then ( serde_json:: Value :: as_str) !=Some ( "X25519" ) 779{ 780return Err ( io:: Error :: other ( "JWK is not X25519" )); 781} 782let x: [ u8 ; 32 ] =jwk_bytes ( jwk, "x" ) ? 783. try_into () 784. map_err ( |_| io:: Error :: other ( "Invalid key length" )) ?; 785let private = jwk. get ( "d" ). is_some (); 786let bytes =if private{ 787let d: [ u8 ; 32 ] =jwk_bytes ( jwk, "d" ) ? 788. try_into () 789. map_err ( |_| io:: Error :: other ( "Invalid key length" )) ?; 790let secret = x25519_dalek:: StaticSecret :: from ( d); 791if x25519_dalek:: PublicKey :: from ( & secret). to_bytes () != x{ 792return Err ( io:: Error :: other ( "JWK public and private values disagree" )); 793} 794 d. to_vec () 795} else { 796 x. to_vec () 797}; 798Ok (( 799ImportedKey { 800 bytes, 801length : 256 , 802exponent : Vec :: new (), 803curve : String :: new (), 804}, 805if private{ "private" } else { "public" }. into (), 806)) 807} 808 _ =>Err ( unsupported ()), 809} 810} 811 812pub ( crate ) fn export_jwk ( 813data : & [ u8 ], 814name : & str , 815hash : & str , 816key_type : & str , 817curve : & str , 818usages : & [ String ], 819extractable : bool , 820) -> io:: Result < serde_json:: Value > { 821let mut value = serde_json:: Map :: new (); 822match name{ 823"RSA-OAEP" |"RSA-PSS" |"RSASSA-PKCS1-V1_5" =>{ 824let ( n, e) =if key_type =="private" { 825let key =RsaPrivateKey :: from_pkcs8_der ( data). map_err ( io:: Error :: other) ?; 826( key. n (). to_bytes_be (), key. e (). to_bytes_be ()) 827} else { 828let key =RsaPublicKey :: from_public_key_der ( data). map_err ( io:: Error :: other) ?; 829( key. n (). to_bytes_be (), key. e (). to_bytes_be ()) 830}; 831 value. insert ( "kty" . into (), "RSA" . into ()); 832 value. insert ( "n" . into (), b64 ( & n). into ()); 833 value. insert ( "e" . into (), b64 ( & e). into ()); 834if key_type =="private" { 835let key =RsaPrivateKey :: from_pkcs8_der ( data). map_err ( io:: Error :: other) ?; 836let primes = key. primes (); 837if primes. len () !=2 { 838return Err ( unsupported ()); 839} 840 value. insert ( "d" . into (), b64 ( & key. d (). to_bytes_be ()). into ()); 841 value. insert ( "p" . into (), b64 ( & primes[ 0 ]. to_bytes_be ()). into ()); 842 value. insert ( "q" . into (), b64 ( & primes[ 1 ]. to_bytes_be ()). into ()); 843 value. insert ( 844"dp" . into (), 845b64 ( & key. dp (). ok_or_else ( unsupported) ?. to_bytes_be ()). into (), 846); 847 value. insert ( 848"dq" . into (), 849b64 ( & key. dq (). ok_or_else ( unsupported) ?. to_bytes_be ()). into (), 850); 851 value. insert ( 852"qi" . into (), 853b64 ( & key. crt_coefficient (). ok_or_else ( unsupported) ?. to_bytes_be ()). into (), 854); 855} 856let prefix =match name{ 857"RSA-OAEP" =>"RSA-OAEP" , 858"RSA-PSS" =>"PS" , 859 _ =>"RS" , 860}; 861let alg =if name =="RSA-OAEP" { 862if hash =="SHA-1" { 863 prefix. into () 864} else { 865format! ( "{prefix}-{}" , & hash[ 4 ..]) 866} 867} else { 868format! ( "{prefix}{}" , & hash[ 4 ..]) 869}; 870 value. insert ( "alg" . into (), alg. into ()); 871} 872"ECDSA" |"ECDH" =>{ 873let ( x, y, d) =match ( curve, key_type) { 874( "P-256" , "private" ) =>{ 875let k = p256:: SecretKey :: from_pkcs8_der ( data). map_err ( io:: Error :: other) ?; 876let p = k. public_key (). to_encoded_point ( false ); 877( 878 p. x (). ok_or_else ( unsupported) ?. to_vec (), 879 p. y (). ok_or_else ( unsupported) ?. to_vec (), 880Some ( k. to_bytes (). to_vec ()), 881) 882} 883( "P-256" , _) =>{ 884let k = p256:: PublicKey :: from_public_key_der ( data). map_err ( io:: Error :: other) ?; 885let p = k. to_encoded_point ( false ); 886( 887 p. x (). ok_or_else ( unsupported) ?. to_vec (), 888 p. y (). ok_or_else ( unsupported) ?. to_vec (), 889None , 890) 891} 892( "P-384" , "private" ) =>{ 893let k = p384:: SecretKey :: from_pkcs8_der ( data). map_err ( io:: Error :: other) ?; 894let p = k. public_key (). to_encoded_point ( false ); 895( 896 p. x (). ok_or_else ( unsupported) ?. to_vec (), 897 p. y (). ok_or_else ( unsupported) ?. to_vec (), 898Some ( k. to_bytes (). to_vec ()), 899) 900} 901( "P-384" , _) =>{ 902let k = p384:: PublicKey :: from_public_key_der ( data). map_err ( io:: Error :: other) ?; 903let p = k. to_encoded_point ( false ); 904( 905 p. x (). ok_or_else ( unsupported) ?. to_vec (), 906 p. y (). ok_or_else ( unsupported) ?. to_vec (), 907None , 908) 909} 910( "P-521" , "private" ) =>{ 911let k = p521:: SecretKey :: from_pkcs8_der ( data). map_err ( io:: Error :: other) ?; 912let p = k. public_key (). to_encoded_point ( false ); 913( 914 p. x (). ok_or_else ( unsupported) ?. to_vec (), 915 p. y (). ok_or_else ( unsupported) ?. to_vec (), 916Some ( k. to_bytes (). to_vec ()), 917) 918} 919( "P-521" , _) =>{ 920let p = p521:: PublicKey :: from_sec1_bytes ( & ec_public_sec1 ( data) ?) 921. map_err ( io:: Error :: other) ? 922. to_encoded_point ( false ); 923( 924 p. x (). ok_or_else ( unsupported) ?. to_vec (), 925 p. y (). ok_or_else ( unsupported) ?. to_vec (), 926None , 927) 928} 929 _ =>return Err ( unsupported ()), 930}; 931 value. insert ( "kty" . into (), "EC" . into ()); 932 value. insert ( "crv" . into (), curve. into ()); 933 value. insert ( "x" . into (), b64 ( & x). into ()); 934 value. insert ( "y" . into (), b64 ( & y). into ()); 935if let Some ( d) = d{ 936 value. insert ( "d" . into (), b64 ( & d). into ()); 937} 938if name =="ECDSA" { 939let alg =match curve{ 940"P-256" =>"ES256" , 941"P-384" =>"ES384" , 942"P-521" =>"ES512" , 943 _ =>return Err ( unsupported ()), 944}; 945 value. insert ( "alg" . into (), alg. into ()); 946} 947} 948"ED25519" =>{ 949let ( x, d) =if key_type =="private" { 950let k = 951 ed25519_dalek:: SigningKey :: from_pkcs8_der ( data). map_err ( io:: Error :: other) ?; 952( 953 k. verifying_key (). to_bytes (). to_vec (), 954Some ( k. to_bytes (). to_vec ()), 955) 956} else { 957( 958 ed25519_dalek:: VerifyingKey :: from_public_key_der ( data) 959. map_err ( io:: Error :: other) ? 960. to_bytes () 961. to_vec (), 962None , 963) 964}; 965 value. insert ( "kty" . into (), "OKP" . into ()); 966 value. insert ( "crv" . into (), "Ed25519" . into ()); 967 value. insert ( "x" . into (), b64 ( & x). into ()); 968if let Some ( d) = d{ 969 value. insert ( "d" . into (), b64 ( & d). into ()); 970} 971 value. insert ( "alg" . into (), "EdDSA" . into ()); 972} 973"X25519" =>{ 974let ( x, d) =if key_type =="private" { 975let d: [ u8 ; 32 ] = data 976. try_into () 977. map_err ( |_| io:: Error :: other ( "Invalid key length" )) ?; 978let s = x25519_dalek:: StaticSecret :: from ( d); 979( 980 x25519_dalek:: PublicKey :: from ( & s). to_bytes (). to_vec (), 981Some ( d. to_vec ()), 982) 983} else { 984( data. to_vec (), None ) 985}; 986 value. insert ( "kty" . into (), "OKP" . into ()); 987 value. insert ( "crv" . into (), "X25519" . into ()); 988 value. insert ( "x" . into (), b64 ( & x). into ()); 989if let Some ( d) = d{ 990 value. insert ( "d" . into (), b64 ( & d). into ()); 991} 992} 993 _ =>return Err ( unsupported ()), 994} 995 value. insert ( 996"key_ops" . into (), 997 serde_json:: to_value ( usages). map_err ( io:: Error :: other) ?, 998); 999 value. insert ( "ext" . into (), extractable. into ()); 1000Ok ( value. into ()) 1001} 1002 1003fn mgf1 < D >( seed : & [ u8 ], output : & mut [ u8 ]) 1004where 1005D : sha2:: Digest , 1006{ 1007let mut counter =0u32 ; 1008let mut offset =0 ; 1009while offset < output. len () { 1010let mut hasher =D :: new (); 1011 hasher. update ( seed); 1012 hasher. update ( counter. to_be_bytes ()); 1013let digest = hasher. finalize (); 1014let digest = digest. as_slice (); 1015let take =( output. len () - offset). min ( digest. len ()); 1016 output[ offset..offset + take]. copy_from_slice ( & digest[ ..take]); 1017 offset += take; 1018 counter = counter. wrapping_add ( 1 ); 1019} 1020} 1021 1022fn oaep_encrypt < D >( public : & RsaPublicKey , label : & [ u8 ], input : & [ u8 ]) -> io:: Result < Vec < u8 >> 1023where 1024D : sha2:: Digest , 1025{ 1026let key_size = public. size (); 1027let hash_size = <D as sha2:: Digest >:: output_size (); 1028if input. len () +2 * hash_size +2 > key_size{ 1029return Err ( io:: Error :: other ( "Invalid RSA-OAEP plaintext length" )); 1030} 1031let db_size = key_size - hash_size -1 ; 1032let mut db =vec! [ 0 ; db_size]; 1033 db[ ..hash_size]. copy_from_slice ( D :: digest ( label). as_slice ()); 1034 db[ db_size - input. len () -1 ] =1 ; 1035 db[ db_size - input. len () ..]. copy_from_slice ( input); 1036let mut seed =Zeroizing :: new ( vec! [ 0 ; hash_size]); 1037OsRng . fill_bytes ( seed. as_mut_slice ()); 1038let mut db_mask =vec! [ 0 ; db_size]; 1039mgf1 ::< D >( & seed, & mut db_mask); 1040for ( byte, mask) in db. iter_mut (). zip ( & db_mask) { 1041* byte ^=* mask; 1042} 1043let mut seed_mask =Zeroizing :: new ( vec! [ 0 ; hash_size]); 1044mgf1 ::< D >( & db, & mut seed_mask); 1045for ( byte, mask) in seed. iter_mut (). zip ( seed_mask. iter ()) { 1046* byte ^=* mask; 1047} 1048let mut encoded =Vec :: with_capacity ( key_size); 1049 encoded. push ( 0 ); 1050 encoded. extend_from_slice ( & seed); 1051 encoded. extend_from_slice ( & db); 1052let encoded = rsa:: BigUint :: from_bytes_be ( & encoded); 1053let encrypted =rsa_encrypt_raw ( public, & encoded). map_err ( io:: Error :: other) ?; 1054let bytes = encrypted. to_bytes_be (); 1055if bytes. len () > key_size{ 1056return Err ( io:: Error :: other ( "Invalid RSA-OAEP ciphertext" )); 1057} 1058let mut output =vec! [ 0 ; key_size]; 1059 output[ key_size - bytes. len () ..]. copy_from_slice ( & bytes); 1060Ok ( output) 1061} 1062 1063fn oaep_decrypt < D >( private : & RsaPrivateKey , label : & [ u8 ], input : & [ u8 ]) -> io:: Result < Vec < u8 >> 1064where 1065D : sha2:: Digest , 1066{ 1067let key_size = private. size (); 1068let hash_size = <D as sha2:: Digest >:: output_size (); 1069if key_size <2 * hash_size +2 || input. len () != key_size{ 1070return Err ( io:: Error :: other ( "Invalid RSA-OAEP ciphertext" )); 1071} 1072let ciphertext = rsa:: BigUint :: from_bytes_be ( input); 1073let mut rng =OsRng ; 1074let encoded = 1075rsa_decrypt_raw ( private, Some ( & mut rng), & ciphertext). map_err ( io:: Error :: other) ?; 1076let bytes = encoded. to_bytes_be (); 1077if bytes. len () > key_size{ 1078return Err ( io:: Error :: other ( "Invalid RSA-OAEP ciphertext" )); 1079} 1080let mut padded =Zeroizing :: new ( vec! [ 0 ; key_size]); 1081 padded[ key_size - bytes. len () ..]. copy_from_slice ( & bytes); 1082let mut failure =( padded[ 0 ] !=0 ) as u8 ; 1083let ( masked_seed, masked_db) = padded[ 1 ..]. split_at ( hash_size); 1084let mut seed =Zeroizing :: new ( vec! [ 0 ; hash_size]); 1085let mut seed_mask =vec! [ 0 ; hash_size]; 1086mgf1 ::< D >( masked_db, & mut seed_mask); 1087for (( byte, masked), mask) in seed 1088. iter_mut () 1089. zip ( masked_seed. iter ()) 1090. zip ( seed_mask. iter ()) 1091{ 1092* byte =* masked ^* mask; 1093} 1094let mut db =Zeroizing :: new ( vec! [ 0 ; key_size - hash_size -1 ]); 1095let mut db_mask =vec! [ 0 ; db. len ()]; 1096mgf1 ::< D >( & seed, & mut db_mask); 1097for (( byte, masked), mask) in db. iter_mut (). zip ( masked_db. iter ()). zip ( db_mask. iter ()) { 1098* byte =* masked ^* mask; 1099} 1100 failure |=( !bool:: from ( db[ ..hash_size]. ct_eq ( D :: digest ( label). as_slice ()))) as u8 ; 1101let mut message_start =0usize ; 1102let mut looking =1u8 ; 1103for ( index, & byte) in db. iter (). enumerate (). skip ( hash_size) { 1104let is_zero =( byte ==0 ) as u8 ; 1105let is_one =( byte ==1 ) as u8 ; 1106 failure |= looking& ( 1 -( is_zero | is_one)); 1107 message_start |=( looking& is_one) as usize * ( index +1 ); 1108 looking &=1 - is_one; 1109} 1110 failure |= looking; 1111if failure !=0 { 1112return Err ( io:: Error :: other ( "Invalid RSA-OAEP ciphertext" )); 1113} 1114Ok ( db[ message_start..]. to_vec ()) 1115} 1116 1117pub ( crate ) fn rsa_encrypt ( 1118name : & str , 1119public_der : & [ u8 ], 1120hash : & str , 1121label : & [ u8 ], 1122input : & [ u8 ], 1123) -> io:: Result < Vec < u8 >> { 1124if name !="RSA-OAEP" { 1125return Err ( unsupported ()); 1126} 1127let key =RsaPublicKey :: from_public_key_der ( public_der). map_err ( io:: Error :: other) ?; 1128macro_rules ! encrypt{ 1129( $digest: ty) =>{ 1130oaep_encrypt ::< $digest>( & key, label, input) 1131}; 1132} 1133match hash{ 1134"SHA-1" =>encrypt! ( sha1:: Sha1 ), 1135"SHA-256" =>encrypt! ( sha2:: Sha256 ), 1136"SHA-384" =>encrypt! ( sha2:: Sha384 ), 1137"SHA-512" =>encrypt! ( sha2:: Sha512 ), 1138 _ =>Err ( unsupported ()), 1139} 1140} 1141 1142pub ( crate ) fn rsa_decrypt ( 1143name : & str , 1144private_der : & [ u8 ], 1145hash : & str , 1146label : & [ u8 ], 1147input : & [ u8 ], 1148) -> io:: Result < Vec < u8 >> { 1149if name !="RSA-OAEP" { 1150return Err ( unsupported ()); 1151} 1152let key =RsaPrivateKey :: from_pkcs8_der ( private_der). map_err ( io:: Error :: other) ?; 1153macro_rules ! decrypt{ 1154( $digest: ty) =>{ 1155oaep_decrypt ::< $digest>( & key, label, input) 1156}; 1157} 1158match hash{ 1159"SHA-1" =>decrypt! ( sha1:: Sha1 ), 1160"SHA-256" =>decrypt! ( sha2:: Sha256 ), 1161"SHA-384" =>decrypt! ( sha2:: Sha384 ), 1162"SHA-512" =>decrypt! ( sha2:: Sha512 ), 1163 _ =>Err ( unsupported ()), 1164} 1165} 1166 1167pub ( crate ) fn rsa_sign ( 1168name : & str , 1169private_der : & [ u8 ], 1170hash : & str , 1171salt_length : usize , 1172input : & [ u8 ], 1173) -> io:: Result < Vec < u8 >> { 1174let hashed =hash_bytes ( hash, input) ?; 1175if name =="RSA-PSS" { 1176let mut rng =OsRng ; 1177macro_rules ! sign{ 1178( $digest: ty) =>{{ 1179let key =RsaPrivateKey :: from_pkcs8_der ( private_der). map_err ( io:: Error :: other) ?; 1180let signing_key = 1181 rsa:: pss:: SigningKey ::< $digest>:: new_with_salt_len ( key, salt_length); 1182 signature:: hazmat:: RandomizedPrehashSigner :: sign_prehash_with_rng ( 1183& signing_key, 1184& mut rng, 1185& hashed, 1186) 1187. map_err ( io:: Error :: other) 1188. map ( |signature|Box ::<[ u8 ]>:: from ( signature). into_vec ()) 1189}}; 1190} 1191match hash{ 1192"SHA-1" =>sign! ( sha1:: Sha1 ), 1193"SHA-256" =>sign! ( sha2:: Sha256 ), 1194"SHA-384" =>sign! ( sha2:: Sha384 ), 1195"SHA-512" =>sign! ( sha2:: Sha512 ), 1196 _ =>Err ( unsupported ()), 1197} 1198} else if name =="RSASSA-PKCS1-V1_5" { 1199macro_rules ! sign{ 1200( $digest: ty) =>{{ 1201let key =RsaPrivateKey :: from_pkcs8_der ( private_der). map_err ( io:: Error :: other) ?; 1202let signing_key = rsa:: pkcs1v15:: SigningKey ::< $digest>:: new ( key); 1203 signature:: hazmat:: PrehashSigner :: sign_prehash ( & signing_key, & hashed) 1204. map_err ( io:: Error :: other) 1205. map ( |signature|Box ::<[ u8 ]>:: from ( signature). into_vec ()) 1206}}; 1207} 1208match hash{ 1209"SHA-1" =>sign! ( sha1:: Sha1 ), 1210"SHA-256" =>sign! ( sha2:: Sha256 ), 1211"SHA-384" =>sign! ( sha2:: Sha384 ), 1212"SHA-512" =>sign! ( sha2:: Sha512 ), 1213 _ =>Err ( unsupported ()), 1214} 1215} else { 1216Err ( unsupported ()) 1217} 1218} 1219 1220pub ( crate ) fn rsa_verify ( 1221name : & str , 1222public_der : & [ u8 ], 1223hash : & str , 1224salt_length : usize , 1225input : & [ u8 ], 1226signature : & [ u8 ], 1227) -> io:: Result < bool > { 1228let hashed =hash_bytes ( hash, input) ?; 1229if name =="RSA-PSS" { 1230macro_rules ! verify{ 1231( $digest: ty) =>{{ 1232let key = 1233RsaPublicKey :: from_public_key_der ( public_der). map_err ( io:: Error :: other) ?; 1234let verifying_key = 1235 rsa:: pss:: VerifyingKey ::< $digest>:: new_with_salt_len ( key, salt_length); 1236let signature = rsa:: pss:: Signature :: try_from ( signature) 1237. map_err ( |_| io:: Error :: other ( "Invalid RSA-PSS signature" )) ?; 1238Ok ( signature:: hazmat:: PrehashVerifier :: verify_prehash ( 1239& verifying_key, 1240& hashed, 1241& signature, 1242) 1243. is_ok ()) 1244}}; 1245} 1246match hash{ 1247"SHA-1" =>verify! ( sha1:: Sha1 ), 1248"SHA-256" =>verify! ( sha2:: Sha256 ), 1249"SHA-384" =>verify! ( sha2:: Sha384 ), 1250"SHA-512" =>verify! ( sha2:: Sha512 ), 1251 _ =>Err ( unsupported ()), 1252} 1253} else if name =="RSASSA-PKCS1-V1_5" { 1254macro_rules ! verify{ 1255( $digest: ty) =>{{ 1256let key = 1257RsaPublicKey :: from_public_key_der ( public_der). map_err ( io:: Error :: other) ?; 1258let verifying_key = rsa:: pkcs1v15:: VerifyingKey ::< $digest>:: new ( key); 1259let signature = rsa:: pkcs1v15:: Signature :: try_from ( signature) 1260. map_err ( |_| io:: Error :: other ( "Invalid RSASSA-PKCS1-V1_5 signature" )) ?; 1261Ok ( signature:: hazmat:: PrehashVerifier :: verify_prehash ( 1262& verifying_key, 1263& hashed, 1264& signature, 1265) 1266. is_ok ()) 1267}}; 1268} 1269match hash{ 1270"SHA-1" =>verify! ( sha1:: Sha1 ), 1271"SHA-256" =>verify! ( sha2:: Sha256 ), 1272"SHA-384" =>verify! ( sha2:: Sha384 ), 1273"SHA-512" =>verify! ( sha2:: Sha512 ), 1274 _ =>Err ( unsupported ()), 1275} 1276} else { 1277Err ( unsupported ()) 1278} 1279} 1280 1281pub ( crate ) fn sign ( 1282name : & str , 1283private_der : & [ u8 ], 1284hash : & str , 1285curve : & str , 1286input : & [ u8 ], 1287) -> io:: Result < Vec < u8 >> { 1288if name =="ED25519" { 1289let key = 1290 ed25519_dalek:: SigningKey :: from_pkcs8_der ( private_der). map_err ( io:: Error :: other) ?; 1291return Ok ( key. sign ( input). to_bytes (). to_vec ()); 1292} 1293macro_rules ! sign_curve{ 1294( $module: ident) =>{{ 1295let key = $module:: ecdsa:: SigningKey :: from_pkcs8_der ( private_der) 1296. map_err ( io:: Error :: other) ?; 1297let digest =hash_bytes ( hash, input) ?; 1298let signature: $module:: ecdsa:: Signature = 1299 signature:: hazmat:: PrehashSigner :: sign_prehash ( & key, & digest) 1300. map_err ( io:: Error :: other) ?; 1301Ok ( signature. to_bytes (). to_vec ()) 1302}}; 1303} 1304match ( name, curve) { 1305( "ECDSA" , "P-256" ) =>match hash{ 1306"SHA-1" =>sign_curve! ( p256), 1307"SHA-256" =>sign_curve! ( p256), 1308"SHA-384" =>sign_curve! ( p256), 1309"SHA-512" =>sign_curve! ( p256), 1310 _ =>Err ( unsupported ()), 1311}, 1312( "ECDSA" , "P-384" ) =>match hash{ 1313"SHA-1" =>sign_curve! ( p384), 1314"SHA-256" =>sign_curve! ( p384), 1315"SHA-384" =>sign_curve! ( p384), 1316"SHA-512" =>sign_curve! ( p384), 1317 _ =>Err ( unsupported ()), 1318}, 1319( "ECDSA" , "P-521" ) =>{ 1320let private = p521:: SecretKey :: from_pkcs8_der ( private_der). map_err ( io:: Error :: other) ?; 1321let key = p521:: ecdsa:: SigningKey :: from_slice ( private. to_bytes (). as_slice ()) 1322. map_err ( io:: Error :: other) ?; 1323let digest =hash_bytes ( hash, input) ?; 1324let signature: p521:: ecdsa:: Signature = 1325 signature:: hazmat:: PrehashSigner :: sign_prehash ( & key, & digest) 1326. map_err ( io:: Error :: other) ?; 1327Ok ( signature. to_bytes (). to_vec ()) 1328} 1329 _ =>Err ( unsupported ()), 1330} 1331} 1332 1333pub ( crate ) fn verify ( 1334name : & str , 1335public_der : & [ u8 ], 1336hash : & str , 1337curve : & str , 1338input : & [ u8 ], 1339signature_bytes : & [ u8 ], 1340) -> io:: Result < bool > { 1341if name =="ED25519" { 1342let key = ed25519_dalek:: VerifyingKey :: from_public_key_der ( public_der) 1343. map_err ( io:: Error :: other) ?; 1344let Ok ( sig) = ed25519_dalek:: Signature :: from_slice ( signature_bytes) else { 1345return Ok ( false ); 1346}; 1347return Ok ( key. verify ( input, & sig). is_ok ()); 1348} 1349macro_rules ! verify_curve{ 1350( $module: ident) =>{{ 1351let key = $module:: ecdsa:: VerifyingKey :: from_public_key_der ( public_der) 1352. map_err ( io:: Error :: other) ?; 1353let Ok ( sig) = $module:: ecdsa:: Signature :: from_slice ( signature_bytes) else { 1354return Ok ( false ); 1355}; 1356let digest =hash_bytes ( hash, input) ?; 1357Ok ( signature:: hazmat:: PrehashVerifier :: verify_prehash ( & key, & digest, & sig). is_ok ()) 1358}}; 1359} 1360match ( name, curve) { 1361( "ECDSA" , "P-256" ) =>verify_curve! ( p256), 1362( "ECDSA" , "P-384" ) =>verify_curve! ( p384), 1363( "ECDSA" , "P-521" ) =>{ 1364let info = pkcs8:: spki:: SubjectPublicKeyInfoRef :: try_from ( public_der) 1365. map_err ( io:: Error :: other) ?; 1366let encoded = info. subject_public_key . as_bytes (). ok_or_else ( unsupported) ?; 1367let key = 1368 p521:: ecdsa:: VerifyingKey :: from_sec1_bytes ( encoded). map_err ( io:: Error :: other) ?; 1369let Ok ( sig) = p521:: ecdsa:: Signature :: from_slice ( signature_bytes) else { 1370return Ok ( false ); 1371}; 1372let digest =hash_bytes ( hash, input) ?; 1373Ok ( signature:: hazmat:: PrehashVerifier :: verify_prehash ( & key, & digest, & sig). is_ok ()) 1374} 1375 _ =>Err ( unsupported ()), 1376} 1377} 1378 1379pub ( crate ) fn ecdh ( 1380name : & str , 1381curve : & str , 1382private_der : & [ u8 ], 1383public_der : & [ u8 ], 1384) -> io:: Result < Vec < u8 >> { 1385macro_rules ! derive{ 1386( $module: ident) =>{{ 1387let private = 1388 $module:: SecretKey :: from_pkcs8_der ( private_der). map_err ( io:: Error :: other) ?; 1389let public = 1390 $module:: PublicKey :: from_public_key_der ( public_der). map_err ( io:: Error :: other) ?; 1391Ok ( 1392 $module:: ecdh:: diffie_hellman ( private. to_nonzero_scalar (), public. as_affine ()) 1393. raw_secret_bytes () 1394. to_vec (), 1395) 1396}}; 1397} 1398match ( name, curve) { 1399( "ECDH" , "P-256" ) =>derive! ( p256), 1400( "ECDH" , "P-384" ) =>derive! ( p384), 1401( "ECDH" , "P-521" ) =>{ 1402let private = p521:: SecretKey :: from_pkcs8_der ( private_der). map_err ( io:: Error :: other) ?; 1403let info = pkcs8:: spki:: SubjectPublicKeyInfoRef :: try_from ( public_der) 1404. map_err ( io:: Error :: other) ?; 1405let encoded = info. subject_public_key . as_bytes (). ok_or_else ( unsupported) ?; 1406let public = p521:: PublicKey :: from_sec1_bytes ( encoded). map_err ( io:: Error :: other) ?; 1407Ok ( 1408 p521:: ecdh:: diffie_hellman ( private. to_nonzero_scalar (), public. as_affine ()) 1409. raw_secret_bytes () 1410. to_vec (), 1411) 1412} 1413 _ =>Err ( unsupported ()), 1414} 1415} 1416 1417pub ( crate ) fn x25519 ( private : & [ u8 ], public : & [ u8 ]) -> io:: Result < Vec < u8 >> { 1418let private: [ u8 ; 32 ] = private 1419. try_into () 1420. map_err ( |_| io:: Error :: other ( "Invalid key length" )) ?; 1421let public: [ u8 ; 32 ] = public 1422. try_into () 1423. map_err ( |_| io:: Error :: other ( "Invalid key length" )) ?; 1424let shared = x25519_dalek:: StaticSecret :: from ( private) 1425. diffie_hellman ( & x25519_dalek:: PublicKey :: from ( public)); 1426if !shared. was_contributory () { 1427return Err ( io:: Error :: other ( 1428"X25519 produced an all-zero shared secret" , 1429)); 1430} 1431Ok ( shared. to_bytes (). to_vec ()) 1432} 1433 1434# [ cfg ( test )] 1435mod tests{ 1436use super :: * ; 1437 1438# [ test ] 1439fn rsa_generation_rejects_invalid_public_exponents_before_keygen () { 1440for exponentin [ & [ 0 ][ ..], & [ 1 ][ ..], & [ 2 ][ ..], & [ 1 , 0 , 2 ][ ..]] { 1441assert! ( generate ( "RSA-PSS" , 1024 , exponent, "" ). is_err ()); 1442} 1443} 1444 1445# [ test ] 1446fn asymmetric_export_rejects_incompatible_key_types () { 1447for ( format, key_type) in [( "raw" , "private" ), ( "pkcs8" , "public" ), ( "spki" , "private" )] { 1448let error =export_key ( format, & [], "ECDSA" , key_type, "P-256" ). unwrap_err (); 1449assert! ( error. to_string (). starts_with ( "InvalidAccessError:" )); 1450} 1451} 1452 1453# [ test ] 1454fn rsa_signing_uses_requested_pss_salt_and_pkcs1 () { 1455let pair =generate ( "RSA-PSS" , 1024 , & [ 1 , 0 , 1 ], "" ). unwrap (); 1456let message =b"private RSA signatures use OpenSSL" ; 1457let signature =rsa_sign ( "RSA-PSS" , & pair. private , "SHA-256" , 32 , message). unwrap (); 1458assert! ( rsa_verify ( "RSA-PSS" , & pair. public , "SHA-256" , 32 , message, & signature). unwrap ()); 1459assert! ( !rsa_verify ( "RSA-PSS" , & pair. public , "SHA-256" , 20 , message, & signature). unwrap ()); 1460let signature = 1461rsa_sign ( "RSASSA-PKCS1-V1_5" , & pair. private , "SHA-256" , 0 , message). unwrap (); 1462assert! ( 1463rsa_verify ( 1464"RSASSA-PKCS1-V1_5" , 1465& pair. public , 1466"SHA-256" , 14670 , 1468 message, 1469& signature 1470) 1471. unwrap () 1472); 1473} 1474}