@@ -645,3 +645,93 @@ if (hasOpenSSL(3, 2)) {
645645 } , { code : 'ERR_OSSL_INVALID_DIGEST_LENGTH' } ) ;
646646 }
647647}
648+
649+ // --- Error: wrong digest length for RSA/ECDSA ---
650+ // OpenSSL rejects wrong-length digests when signing. When verifying,
651+ // it returns false (signature mismatch) rather than throwing.
652+ {
653+ const rsaDigestLengthError = hasOpenSSL ( 3 , 0 ) ?
654+ 'ERR_OSSL_INVALID_DIGEST_LENGTH' :
655+ 'ERR_OSSL_RSA_INVALID_DIGEST_LENGTH' ;
656+
657+ // RSA PKCS#1 v1.5
658+ {
659+ const privKey = fixtures . readKey ( 'rsa_private_2048.pem' , 'ascii' ) ;
660+ const pubKey = fixtures . readKey ( 'rsa_public_2048.pem' , 'ascii' ) ;
661+ const correctDigest = crypto . createHash ( 'sha256' ) . update ( data ) . digest ( ) ;
662+ const goodSig = crypto . signDigest ( 'sha256' , correctDigest , privKey ) ;
663+
664+ // Too short
665+ assert . throws ( ( ) => {
666+ crypto . signDigest ( 'sha256' , Buffer . alloc ( 16 ) , privKey ) ;
667+ } , { code : rsaDigestLengthError } ) ;
668+
669+ // Too long
670+ assert . throws ( ( ) => {
671+ crypto . signDigest ( 'sha256' , Buffer . alloc ( 64 ) , privKey ) ;
672+ } , { code : rsaDigestLengthError } ) ;
673+
674+ // Verify with wrong-length digest returns false
675+ assert . strictEqual (
676+ crypto . verifyDigest ( 'sha256' , Buffer . alloc ( 16 ) , pubKey , goodSig ) , false ) ;
677+ }
678+
679+ // RSA-PSS
680+ {
681+ const privKey = fixtures . readKey ( 'rsa_private_2048.pem' , 'ascii' ) ;
682+ const pubKey = fixtures . readKey ( 'rsa_public_2048.pem' , 'ascii' ) ;
683+ const correctDigest = crypto . createHash ( 'sha256' ) . update ( data ) . digest ( ) ;
684+ const goodSig = crypto . signDigest ( 'sha256' , correctDigest , {
685+ key : privKey ,
686+ padding : crypto . constants . RSA_PKCS1_PSS_PADDING ,
687+ saltLength : 32 ,
688+ } ) ;
689+
690+ assert . throws ( ( ) => {
691+ crypto . signDigest ( 'sha256' , Buffer . alloc ( 16 ) , {
692+ key : privKey ,
693+ padding : crypto . constants . RSA_PKCS1_PSS_PADDING ,
694+ saltLength : 32 ,
695+ } ) ;
696+ } , { code : rsaDigestLengthError } ) ;
697+
698+ assert . strictEqual (
699+ crypto . verifyDigest ( 'sha256' , Buffer . alloc ( 16 ) , {
700+ key : pubKey ,
701+ padding : crypto . constants . RSA_PKCS1_PSS_PADDING ,
702+ saltLength : 32 ,
703+ } , goodSig ) , false ) ;
704+ }
705+
706+ // ECDSA — OpenSSL 3.x rejects wrong-length digests; 1.1.x accepts them.
707+ {
708+ const privKey = fixtures . readKey ( 'ec_p256_private.pem' , 'ascii' ) ;
709+ const pubKey = fixtures . readKey ( 'ec_p256_public.pem' , 'ascii' ) ;
710+ const correctDigest = crypto . createHash ( 'sha256' ) . update ( data ) . digest ( ) ;
711+ const goodSig = crypto . signDigest ( 'sha256' , correctDigest , privKey ) ;
712+
713+ if ( hasOpenSSL ( 3 , 0 ) ) {
714+ const ecdsaDigestLengthError = hasOpenSSL ( 3 , 2 ) ?
715+ 'ERR_OSSL_EVP_PROVIDER_SIGNATURE_FAILURE' :
716+ 'ERR_CRYPTO_OPERATION_FAILED' ;
717+
718+ // Too short
719+ assert . throws ( ( ) => {
720+ crypto . signDigest ( 'sha256' , Buffer . alloc ( 16 ) , privKey ) ;
721+ } , { code : ecdsaDigestLengthError } ) ;
722+
723+ // Too long
724+ assert . throws ( ( ) => {
725+ crypto . signDigest ( 'sha256' , Buffer . alloc ( 64 ) , privKey ) ;
726+ } , { code : ecdsaDigestLengthError } ) ;
727+ } else {
728+ // OpenSSL 1.1.x signs any length digest for ECDSA without error
729+ assert . ok ( crypto . signDigest ( 'sha256' , Buffer . alloc ( 16 ) , privKey ) ) ;
730+ assert . ok ( crypto . signDigest ( 'sha256' , Buffer . alloc ( 64 ) , privKey ) ) ;
731+ }
732+
733+ // Verify with wrong-length digest returns false on all versions
734+ assert . strictEqual (
735+ crypto . verifyDigest ( 'sha256' , Buffer . alloc ( 16 ) , pubKey , goodSig ) , false ) ;
736+ }
737+ }
0 commit comments