@@ -659,7 +659,7 @@ sc_pkcs15emu_oberthur_add_cert(struct sc_pkcs15_card *p15card, unsigned int file
659659 struct sc_context * ctx = p15card -> card -> ctx ;
660660 struct sc_pkcs15_cert_info cinfo ;
661661 struct sc_pkcs15_object cobj ;
662- unsigned char * info_blob , * cert_blob ;
662+ unsigned char * info_blob = NULL , * cert_blob = NULL ;
663663 size_t info_len , cert_len , len , offs ;
664664 unsigned flags ;
665665 int rv ;
@@ -675,31 +675,47 @@ sc_pkcs15emu_oberthur_add_cert(struct sc_pkcs15_card *p15card, unsigned int file
675675 rv = sc_oberthur_read_file (p15card , ch_tmp , & info_blob , & info_len , 1 );
676676 LOG_TEST_RET (ctx , rv , "Failed to add certificate: read oberthur file error" );
677677
678- if (info_len < 2 )
678+ if (info_len < 2 ) {
679+ free (info_blob );
679680 LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add certificate: no 'tag'" );
681+ }
680682 flags = * (info_blob + 0 ) * 0x100 + * (info_blob + 1 );
681683 offs = 2 ;
682684
683685 /* Label */
684- if (offs + 2 > info_len )
686+ if (offs + 2 > info_len ) {
687+ free (info_blob );
685688 LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add certificate: no 'CN'" );
689+ }
686690 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 ) {
688695 if (len > sizeof (cobj .label ) - 1 )
689696 len = sizeof (cobj .label ) - 1 ;
690697 memcpy (cobj .label , info_blob + offs + 2 , len );
691698 }
692699 offs += 2 + len ;
693700
694701 /* ID */
695- if (offs > info_len )
702+ if (offs + 2 > info_len ) {
703+ free (info_blob );
696704 LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add certificate: no 'ID'" );
705+ }
697706 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 );
699712 LOG_TEST_RET (ctx , SC_ERROR_INVALID_DATA , "Failed to add certificate: invalid 'ID' length" );
713+ }
700714 memcpy (cinfo .id .value , info_blob + offs + 2 , len );
701715 cinfo .id .len = len ;
702716
717+ free (info_blob );
718+
703719 /* Ignore subject, issuer and serial */
704720
705721 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,
784800 rv = sc_oberthur_read_file (p15card , ch_tmp , & info_blob , & info_len , 1 );
785801 LOG_TEST_RET (ctx , rv , "Failed to add private key: read oberthur file error" );
786802
787- if (info_len < 2 )
803+ if (info_len < 2 ) {
804+ free (info_blob );
788805 LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add private key: no 'tag'" );
806+ }
789807 flags = * (info_blob + 0 ) * 0x100 + * (info_blob + 1 );
790808 offs = 2 ;
791809
792810 /* CN */
793- if (offs > info_len )
811+ if (offs + 2 > info_len ) {
812+ free (info_blob );
794813 LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add private key: no 'CN'" );
814+ }
795815 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+ }
796820 if (len && !strlen (kobj .label )) {
797821 if (len > sizeof (kobj .label ) - 1 )
798822 len = sizeof (kobj .label ) - 1 ;
@@ -801,13 +825,21 @@ sc_pkcs15emu_oberthur_add_prvkey(struct sc_pkcs15_card *p15card,
801825 offs += 2 + len ;
802826
803827 /* ID */
804- if (offs > info_len )
828+ if (offs + 2 > info_len ) {
829+ free (info_blob );
805830 LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add private key: no 'ID'" );
831+ }
806832 len = * (info_blob + offs + 1 ) + * (info_blob + offs ) * 0x100 ;
807- if (!len )
833+ if (!len ) {
834+ free (info_blob );
808835 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 );
810841 LOG_TEST_RET (ctx , SC_ERROR_INVALID_DATA , "Failed to add private key: invalid ID length" );
842+ }
811843 memcpy (kinfo .id .value , info_blob + offs + 2 , len );
812844 kinfo .id .len = len ;
813845 offs += 2 + len ;
@@ -816,19 +848,28 @@ sc_pkcs15emu_oberthur_add_prvkey(struct sc_pkcs15_card *p15card,
816848 offs += 16 ;
817849
818850 /* 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+ }
821855 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 ) {
823860 kinfo .subject .value = malloc (len );
824- if (!kinfo .subject .value )
861+ if (!kinfo .subject .value ) {
862+ free (info_blob );
825863 LOG_TEST_RET (ctx , SC_ERROR_OUT_OF_MEMORY , "Failed to add private key: memory allocation error" );
864+ }
826865 kinfo .subject .len = len ;
827866 memcpy (kinfo .subject .value , info_blob + offs + 2 , len );
828867 }
829868
830869 /* Modulus and exponent are ignored */
831870
871+ free (info_blob );
872+
832873 snprintf (ch_tmp , sizeof (ch_tmp ), "%s%04X" , AWP_OBJECTS_DF_PRV , file_id );
833874 sc_format_path (ch_tmp , & kinfo .path );
834875 sc_log (ctx , "Private key info path %s" , ch_tmp );
@@ -899,22 +940,30 @@ sc_pkcs15emu_oberthur_add_data(struct sc_pkcs15_card *p15card,
899940 offs += 2 + * (info_blob + offs + 1 );
900941
901942 /* Application */
902- if (offs > info_len ) {
943+ if (offs + 2 > info_len ) {
903944 free (info_blob );
904945 LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add data: no 'application'" );
905946 }
906947 app = info_blob + offs + 2 ;
907948 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+ }
908953 if (app_len > sizeof (dinfo .app_label ) - 1 )
909954 app_len = sizeof (dinfo .app_label ) - 1 ;
910955 offs += 2 + app_len ;
911956
912957 /* OID encode like DER(ASN.1(oid)) */
913- if (offs + 1 > info_len ) {
958+ if (offs + 2 > info_len ) {
914959 free (info_blob );
915960 LOG_TEST_RET (ctx , SC_ERROR_UNKNOWN_DATA_RECEIVED , "Failed to add data: no 'OID'" );
916961 }
917962 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+ }
918967 if (oid_len ) {
919968 oid = info_blob + offs + 2 ;
920969 if (* oid != 0x06 || (* (oid + 1 ) != oid_len - 2 )) {
0 commit comments