@@ -678,6 +678,32 @@ int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
678
678
}
679
679
680
680
#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
+
681
707
/*
682
708
* Parse a PKCS#1 encoded private RSA key
683
709
*/
@@ -730,46 +756,36 @@ static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa,
730
756
}
731
757
732
758
/* 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 )
737
762
goto cleanup ;
738
- p += len ;
739
763
740
764
/* 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 )
745
768
goto cleanup ;
746
- p += len ;
747
769
748
770
/* 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 )
753
774
goto cleanup ;
754
- p += len ;
755
775
756
776
/* 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 )
761
780
goto cleanup ;
762
- p += len ;
763
781
764
782
/* 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 )
769
786
goto cleanup ;
770
- p += len ;
771
787
772
- #if !defined(MBEDTLS_RSA_NO_CRT )
788
+ #if !defined(MBEDTLS_RSA_NO_CRT ) && !defined( MBEDTLS_RSA_ALT )
773
789
/*
774
790
* The RSA CRT parameters DP, DQ and QP are nominally redundant, in
775
791
* 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,
782
798
*/
783
799
784
800
/* 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 )
786
803
goto cleanup ;
787
804
788
805
/* 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 )
790
808
goto cleanup ;
791
809
792
810
/* 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 )
794
813
goto cleanup ;
795
814
796
815
#else
797
816
/* 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 )
801
820
goto cleanup ;
802
821
#endif
803
822
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
+ {
806
835
goto cleanup ;
836
+ }
807
837
808
838
if ( p != end )
809
839
{
0 commit comments