@@ -678,6 +678,32 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
678678}
679679
680680#if defined(MBEDTLS_RSA_C )
681+ /*
682+ * Wrapper around mbedtls_asn1_get_mpi() that rejects zero.
683+ *
684+ * The value zero is:
685+ * - never a valid value for an RSA parameter
686+ * - interpreted as "omitted, please reconstruct" by mbedtls_rsa_complete().
687+ *
688+ * Since values can't be omitted in PKCS#1, passing a zero value to
689+ * rsa_complete() would be incorrect, so reject zero values early.
690+ */
691+ static int asn1_get_nonzero_mpi ( unsigned char * * p ,
692+ const unsigned char * end ,
693+ mbedtls_mpi * X )
694+ {
695+ int ret ;
696+
697+ ret = mbedtls_asn1_get_mpi ( p , end , X );
698+ if ( ret != 0 )
699+ return ( ret );
700+
701+ if ( mbedtls_mpi_cmp_int ( X , 0 ) == 0 )
702+ return ( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT );
703+
704+ return ( 0 );
705+ }
706+
681707/*
682708 * Parse a PKCS#1 encoded private RSA key
683709 */
@@ -730,46 +756,36 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
730756 }
731757
732758 /* Import N */
733- if ( ( ret = mbedtls_asn1_get_tag ( & p , end , & len ,
734- MBEDTLS_ASN1_INTEGER ) ) != 0 ||
735- ( ret = mbedtls_rsa_import_raw ( rsa , p , len , NULL , 0 , NULL , 0 ,
736- NULL , 0 , NULL , 0 ) ) != 0 )
759+ if ( ( ret = asn1_get_nonzero_mpi ( & p , end , & T ) ) != 0 ||
760+ ( ret = mbedtls_rsa_import ( rsa , & T , NULL , NULL ,
761+ NULL , NULL ) ) != 0 )
737762 goto cleanup ;
738- p += len ;
739763
740764 /* Import E */
741- if ( ( ret = mbedtls_asn1_get_tag ( & p , end , & len ,
742- MBEDTLS_ASN1_INTEGER ) ) != 0 ||
743- ( ret = mbedtls_rsa_import_raw ( rsa , NULL , 0 , NULL , 0 , NULL , 0 ,
744- NULL , 0 , p , len ) ) != 0 )
765+ if ( ( ret = asn1_get_nonzero_mpi ( & p , end , & T ) ) != 0 ||
766+ ( ret = mbedtls_rsa_import ( rsa , NULL , NULL , NULL ,
767+ NULL , & T ) ) != 0 )
745768 goto cleanup ;
746- p += len ;
747769
748770 /* Import D */
749- if ( ( ret = mbedtls_asn1_get_tag ( & p , end , & len ,
750- MBEDTLS_ASN1_INTEGER ) ) != 0 ||
751- ( ret = mbedtls_rsa_import_raw ( rsa , NULL , 0 , NULL , 0 , NULL , 0 ,
752- p , len , NULL , 0 ) ) != 0 )
771+ if ( ( ret = asn1_get_nonzero_mpi ( & p , end , & T ) ) != 0 ||
772+ ( ret = mbedtls_rsa_import ( rsa , NULL , NULL , NULL ,
773+ & T , NULL ) ) != 0 )
753774 goto cleanup ;
754- p += len ;
755775
756776 /* Import P */
757- if ( ( ret = mbedtls_asn1_get_tag ( & p , end , & len ,
758- MBEDTLS_ASN1_INTEGER ) ) != 0 ||
759- ( ret = mbedtls_rsa_import_raw ( rsa , NULL , 0 , p , len , NULL , 0 ,
760- NULL , 0 , NULL , 0 ) ) != 0 )
777+ if ( ( ret = asn1_get_nonzero_mpi ( & p , end , & T ) ) != 0 ||
778+ ( ret = mbedtls_rsa_import ( rsa , NULL , & T , NULL ,
779+ NULL , NULL ) ) != 0 )
761780 goto cleanup ;
762- p += len ;
763781
764782 /* Import Q */
765- if ( ( ret = mbedtls_asn1_get_tag ( & p , end , & len ,
766- MBEDTLS_ASN1_INTEGER ) ) != 0 ||
767- ( ret = mbedtls_rsa_import_raw ( rsa , NULL , 0 , NULL , 0 , p , len ,
768- NULL , 0 , NULL , 0 ) ) != 0 )
783+ if ( ( ret = asn1_get_nonzero_mpi ( & p , end , & T ) ) != 0 ||
784+ ( ret = mbedtls_rsa_import ( rsa , NULL , NULL , & T ,
785+ NULL , NULL ) ) != 0 )
769786 goto cleanup ;
770- p += len ;
771787
772- #if !defined(MBEDTLS_RSA_NO_CRT )
788+ #if !defined(MBEDTLS_RSA_NO_CRT ) && !defined( MBEDTLS_RSA_ALT )
773789 /*
774790 * The RSA CRT parameters DP, DQ and QP are nominally redundant, in
775791 * that they can be easily recomputed from D, P and Q. However by
@@ -782,28 +798,42 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
782798 */
783799
784800 /* Import DP */
785- if ( ( ret = mbedtls_asn1_get_mpi ( & p , end , & rsa -> DP ) ) != 0 )
801+ if ( ( ret = asn1_get_nonzero_mpi ( & p , end , & T ) ) != 0 ||
802+ ( ret = mbedtls_mpi_copy ( & rsa -> DP , & T ) ) != 0 )
786803 goto cleanup ;
787804
788805 /* Import DQ */
789- if ( ( ret = mbedtls_asn1_get_mpi ( & p , end , & rsa -> DQ ) ) != 0 )
806+ if ( ( ret = asn1_get_nonzero_mpi ( & p , end , & T ) ) != 0 ||
807+ ( ret = mbedtls_mpi_copy ( & rsa -> DQ , & T ) ) != 0 )
790808 goto cleanup ;
791809
792810 /* Import QP */
793- if ( ( ret = mbedtls_asn1_get_mpi ( & p , end , & rsa -> QP ) ) != 0 )
811+ if ( ( ret = asn1_get_nonzero_mpi ( & p , end , & T ) ) != 0 ||
812+ ( ret = mbedtls_mpi_copy ( & rsa -> QP , & T ) ) != 0 )
794813 goto cleanup ;
795814
796815#else
797816 /* Verify existance of the CRT params */
798- if ( ( ret = mbedtls_asn1_get_mpi ( & p , end , & T ) ) != 0 ||
799- ( ret = mbedtls_asn1_get_mpi ( & p , end , & T ) ) != 0 ||
800- ( ret = mbedtls_asn1_get_mpi ( & p , end , & T ) ) != 0 )
817+ if ( ( ret = asn1_get_nonzero_mpi ( & p , end , & T ) ) != 0 ||
818+ ( ret = asn1_get_nonzero_mpi ( & p , end , & T ) ) != 0 ||
819+ ( ret = asn1_get_nonzero_mpi ( & p , end , & T ) ) != 0 )
801820 goto cleanup ;
802821#endif
803822
804- /* Complete the RSA private key */
805- if ( ( ret = mbedtls_rsa_complete ( rsa ) ) != 0 )
823+ /* rsa_complete() doesn't complete anything with the default
824+ * implementation but is still called:
825+ * - for the benefit of alternative implementation that may want to
826+ * pre-compute stuff beyond what's provided (eg Montgomery factors)
827+ * - as is also sanity-checks the key
828+ *
829+ * Furthermore, we also check the public part for consistency with
830+ * mbedtls_pk_parse_pubkey(), as it includes size minima for example.
831+ */
832+ if ( ( ret = mbedtls_rsa_complete ( rsa ) ) != 0 ||
833+ ( ret = mbedtls_rsa_check_pubkey ( rsa ) ) != 0 )
834+ {
806835 goto cleanup ;
836+ }
807837
808838 if ( p != end )
809839 {
0 commit comments