@@ -659,7 +659,7 @@ sc_pkcs15emu_oberthur_add_cert(struct sc_pkcs15_card *p15card, unsigned int file
659
659
struct sc_context * ctx = p15card -> card -> ctx ;
660
660
struct sc_pkcs15_cert_info cinfo ;
661
661
struct sc_pkcs15_object cobj ;
662
- unsigned char * info_blob , * cert_blob ;
662
+ unsigned char * info_blob = NULL , * cert_blob = NULL ;
663
663
size_t info_len , cert_len , len , offs ;
664
664
unsigned flags ;
665
665
int rv ;
@@ -675,31 +675,47 @@ sc_pkcs15emu_oberthur_add_cert(struct sc_pkcs15_card *p15card, unsigned int file
675
675
rv = sc_oberthur_read_file (p15card , ch_tmp , & info_blob , & info_len , 1 );
676
676
LOG_TEST_RET (ctx , rv , "Failed to add certificate: read oberthur file error" );
677
677
678
- if (info_len < 2 )
678
+ if (info_len < 2 ) {
679
+ free (info_blob );
679
680
LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add certificate: no 'tag'" );
681
+ }
680
682
flags = * (info_blob + 0 ) * 0x100 + * (info_blob + 1 );
681
683
offs = 2 ;
682
684
683
685
/* Label */
684
- if (offs + 2 > info_len )
686
+ if (offs + 2 > info_len ) {
687
+ free (info_blob );
685
688
LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add certificate: no 'CN'" );
689
+ }
686
690
len = * (info_blob + offs + 1 ) + * (info_blob + offs ) * 0x100 ;
687
- if (len ) {
691
+ if (len + offs + 2 > info_len ) {
692
+ free (info_blob );
693
+ LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Invalid 'CN' length" );
694
+ } else if (len ) {
688
695
if (len > sizeof (cobj .label ) - 1 )
689
696
len = sizeof (cobj .label ) - 1 ;
690
697
memcpy (cobj .label , info_blob + offs + 2 , len );
691
698
}
692
699
offs += 2 + len ;
693
700
694
701
/* ID */
695
- if (offs > info_len )
702
+ if (offs + 2 > info_len ) {
703
+ free (info_blob );
696
704
LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add certificate: no 'ID'" );
705
+ }
697
706
len = * (info_blob + offs + 1 ) + * (info_blob + offs ) * 0x100 ;
698
- if (len > sizeof (cinfo .id .value ))
707
+ if (len + offs + 2 > info_len ) {
708
+ free (info_blob );
709
+ LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Invalid 'ID' length" );
710
+ } else if (len > sizeof (cinfo .id .value )) {
711
+ free (info_blob );
699
712
LOG_TEST_RET (ctx , SC_ERROR_INVALID_DATA , "Failed to add certificate: invalid 'ID' length" );
713
+ }
700
714
memcpy (cinfo .id .value , info_blob + offs + 2 , len );
701
715
cinfo .id .len = len ;
702
716
717
+ free (info_blob );
718
+
703
719
/* Ignore subject, issuer and serial */
704
720
705
721
snprintf (ch_tmp , sizeof (ch_tmp ), "%s%04X" , AWP_OBJECTS_DF_PUB , file_id );
@@ -784,15 +800,23 @@ sc_pkcs15emu_oberthur_add_prvkey(struct sc_pkcs15_card *p15card,
784
800
rv = sc_oberthur_read_file (p15card , ch_tmp , & info_blob , & info_len , 1 );
785
801
LOG_TEST_RET (ctx , rv , "Failed to add private key: read oberthur file error" );
786
802
787
- if (info_len < 2 )
803
+ if (info_len < 2 ) {
804
+ free (info_blob );
788
805
LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add private key: no 'tag'" );
806
+ }
789
807
flags = * (info_blob + 0 ) * 0x100 + * (info_blob + 1 );
790
808
offs = 2 ;
791
809
792
810
/* CN */
793
- if (offs > info_len )
811
+ if (offs + 2 > info_len ) {
812
+ free (info_blob );
794
813
LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add private key: no 'CN'" );
814
+ }
795
815
len = * (info_blob + offs + 1 ) + * (info_blob + offs ) * 0x100 ;
816
+ if (len + offs + 2 > info_len ) {
817
+ free (info_blob );
818
+ LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Invalid 'CN' length" );
819
+ }
796
820
if (len && !strlen (kobj .label )) {
797
821
if (len > sizeof (kobj .label ) - 1 )
798
822
len = sizeof (kobj .label ) - 1 ;
@@ -801,13 +825,21 @@ sc_pkcs15emu_oberthur_add_prvkey(struct sc_pkcs15_card *p15card,
801
825
offs += 2 + len ;
802
826
803
827
/* ID */
804
- if (offs > info_len )
828
+ if (offs + 2 > info_len ) {
829
+ free (info_blob );
805
830
LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add private key: no 'ID'" );
831
+ }
806
832
len = * (info_blob + offs + 1 ) + * (info_blob + offs ) * 0x100 ;
807
- if (!len )
833
+ if (!len ) {
834
+ free (info_blob );
808
835
LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add private key: zero length ID" );
809
- else if (len > sizeof (kinfo .id .value ))
836
+ } else if (len + offs + 2 > info_len ) {
837
+ free (info_blob );
838
+ LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Invalid 'ID' length" );
839
+ } else if (len > sizeof (kinfo .id .value )) {
840
+ free (info_blob );
810
841
LOG_TEST_RET (ctx , SC_ERROR_INVALID_DATA , "Failed to add private key: invalid ID length" );
842
+ }
811
843
memcpy (kinfo .id .value , info_blob + offs + 2 , len );
812
844
kinfo .id .len = len ;
813
845
offs += 2 + len ;
@@ -816,19 +848,28 @@ sc_pkcs15emu_oberthur_add_prvkey(struct sc_pkcs15_card *p15card,
816
848
offs += 16 ;
817
849
818
850
/* Subject encoded in ASN1 */
819
- if (offs > info_len )
820
- return SC_ERROR_UNKNOWN_DATA_RECEIVED ;
851
+ if (offs + 2 > info_len ) {
852
+ free (info_blob );
853
+ LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add private key: no 'subject'" );
854
+ }
821
855
len = * (info_blob + offs + 1 ) + * (info_blob + offs ) * 0x100 ;
822
- if (len ) {
856
+ if (len + offs + 2 > info_len ) {
857
+ free (info_blob );
858
+ LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Invalid 'subject' length" );
859
+ } else if (len ) {
823
860
kinfo .subject .value = malloc (len );
824
- if (!kinfo .subject .value )
861
+ if (!kinfo .subject .value ) {
862
+ free (info_blob );
825
863
LOG_TEST_RET (ctx , SC_ERROR_OUT_OF_MEMORY , "Failed to add private key: memory allocation error" );
864
+ }
826
865
kinfo .subject .len = len ;
827
866
memcpy (kinfo .subject .value , info_blob + offs + 2 , len );
828
867
}
829
868
830
869
/* Modulus and exponent are ignored */
831
870
871
+ free (info_blob );
872
+
832
873
snprintf (ch_tmp , sizeof (ch_tmp ), "%s%04X" , AWP_OBJECTS_DF_PRV , file_id );
833
874
sc_format_path (ch_tmp , & kinfo .path );
834
875
sc_log (ctx , "Private key info path %s" , ch_tmp );
@@ -899,22 +940,30 @@ sc_pkcs15emu_oberthur_add_data(struct sc_pkcs15_card *p15card,
899
940
offs += 2 + * (info_blob + offs + 1 );
900
941
901
942
/* Application */
902
- if (offs > info_len ) {
943
+ if (offs + 2 > info_len ) {
903
944
free (info_blob );
904
945
LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add data: no 'application'" );
905
946
}
906
947
app = info_blob + offs + 2 ;
907
948
app_len = * (info_blob + offs + 1 ) + * (info_blob + offs ) * 0x100 ;
949
+ if (offs + 2 + app_len > info_len ) {
950
+ free (info_blob );
951
+ LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Invalid length of 'application' received" );
952
+ }
908
953
if (app_len > sizeof (dinfo .app_label ) - 1 )
909
954
app_len = sizeof (dinfo .app_label ) - 1 ;
910
955
offs += 2 + app_len ;
911
956
912
957
/* OID encode like DER(ASN.1(oid)) */
913
- if (offs + 1 > info_len ) {
958
+ if (offs + 2 > info_len ) {
914
959
free (info_blob );
915
960
LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add data: no 'OID'" );
916
961
}
917
962
oid_len = * (info_blob + offs + 1 ) + * (info_blob + offs ) * 0x100 ;
963
+ if (offs + 2 + oid_len > info_len ) {
964
+ free (info_blob );
965
+ LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Invalid length of 'oid' received" );
966
+ }
918
967
if (oid_len ) {
919
968
oid = info_blob + offs + 2 ;
920
969
if (* oid != 0x06 || (* (oid + 1 ) != oid_len - 2 )) {
0 commit comments