@@ -631,3 +631,114 @@ assert.throws(
631631 assert ( stdout . includes ( 'Verified OK' ) ) ;
632632 } ) ) ;
633633}
634+
635+ {
636+ // Test RSA-PSS.
637+ {
638+ // This key pair does not restrict the message digest algorithm or salt
639+ // length.
640+ const publicPem = fixtures . readKey ( 'rsa_pss_public_2048.pem' ) ;
641+ const privatePem = fixtures . readKey ( 'rsa_pss_private_2048.pem' ) ;
642+
643+ const publicKey = crypto . createPublicKey ( publicPem ) ;
644+ const privateKey = crypto . createPrivateKey ( privatePem ) ;
645+
646+ for ( const key of [ privatePem , privateKey ] ) {
647+ // Any algorithm should work.
648+ for ( const algo of [ 'sha1' , 'sha256' ] ) {
649+ // Any salt length should work.
650+ for ( const saltLength of [ undefined , 8 , 10 , 12 , 16 , 18 , 20 ] ) {
651+ const signature = crypto . sign ( algo , 'foo' , { key, saltLength } ) ;
652+
653+ for ( const pkey of [ key , publicKey , publicPem ] ) {
654+ const okay = crypto . verify (
655+ algo ,
656+ 'foo' ,
657+ { key : pkey , saltLength } ,
658+ signature
659+ ) ;
660+
661+ assert . ok ( okay ) ;
662+ }
663+ }
664+ }
665+ }
666+ }
667+
668+ {
669+ // This key pair enforces sha256 as the message digest and the MGF1
670+ // message digest and a salt length of at least 16 bytes.
671+ const publicPem =
672+ fixtures . readKey ( 'rsa_pss_public_2048_sha256_sha256_16.pem' ) ;
673+ const privatePem =
674+ fixtures . readKey ( 'rsa_pss_private_2048_sha256_sha256_16.pem' ) ;
675+
676+ const publicKey = crypto . createPublicKey ( publicPem ) ;
677+ const privateKey = crypto . createPrivateKey ( privatePem ) ;
678+
679+ for ( const key of [ privatePem , privateKey ] ) {
680+ // Signing with anything other than sha256 should fail.
681+ assert . throws ( ( ) => {
682+ crypto . sign ( 'sha1' , 'foo' , key ) ;
683+ } , / d i g e s t n o t a l l o w e d / ) ;
684+
685+ // Signing with salt lengths less than 16 bytes should fail.
686+ for ( const saltLength of [ 8 , 10 , 12 ] ) {
687+ assert . throws ( ( ) => {
688+ crypto . sign ( 'sha256' , 'foo' , { key, saltLength } ) ;
689+ } , / p s s s a l t l e n t o o s m a l l / ) ;
690+ }
691+
692+ // Signing with sha256 and appropriate salt lengths should work.
693+ for ( const saltLength of [ undefined , 16 , 18 , 20 ] ) {
694+ const signature = crypto . sign ( 'sha256' , 'foo' , { key, saltLength } ) ;
695+
696+ for ( const pkey of [ key , publicKey , publicPem ] ) {
697+ const okay = crypto . verify (
698+ 'sha256' ,
699+ 'foo' ,
700+ { key : pkey , saltLength } ,
701+ signature
702+ ) ;
703+
704+ assert . ok ( okay ) ;
705+ }
706+ }
707+ }
708+ }
709+
710+ {
711+ // This key enforces sha512 as the message digest and sha256 as the MGF1
712+ // message digest.
713+ const publicPem =
714+ fixtures . readKey ( 'rsa_pss_public_2048_sha512_sha256_20.pem' ) ;
715+ const privatePem =
716+ fixtures . readKey ( 'rsa_pss_private_2048_sha512_sha256_20.pem' ) ;
717+
718+ const publicKey = crypto . createPublicKey ( publicPem ) ;
719+ const privateKey = crypto . createPrivateKey ( privatePem ) ;
720+
721+ // Node.js usually uses the same hash function for the message and for MGF1.
722+ // However, when a different MGF1 message digest algorithm has been
723+ // specified as part of the key, it should automatically switch to that.
724+ // This behavior is required by sections 3.1 and 3.3 of RFC4055.
725+ for ( const key of [ privatePem , privateKey ] ) {
726+ // sha256 matches the MGF1 hash function and should be used internally,
727+ // but it should not be permitted as the main message digest algorithm.
728+ for ( const algo of [ 'sha1' , 'sha256' ] ) {
729+ assert . throws ( ( ) => {
730+ crypto . sign ( algo , 'foo' , key ) ;
731+ } , / d i g e s t n o t a l l o w e d / ) ;
732+ }
733+
734+ // sha512 should produce a valid signature.
735+ const signature = crypto . sign ( 'sha512' , 'foo' , key ) ;
736+
737+ for ( const pkey of [ key , publicKey , publicPem ] ) {
738+ const okay = crypto . verify ( 'sha512' , 'foo' , pkey , signature ) ;
739+
740+ assert . ok ( okay ) ;
741+ }
742+ }
743+ }
744+ }
0 commit comments