@@ -652,18 +652,45 @@ word32 CertDecoder::GetDigest()
652652}
653653
654654
655+ char *CertDecoder::AddTag (char *ptr, const char *buf_end,
656+ const char *tag_name, word32 tag_name_length,
657+ word32 tag_value_length)
658+ {
659+ if (ptr + tag_name_length + tag_value_length > buf_end)
660+ return 0 ;
661+
662+ memcpy (ptr, tag_name, tag_name_length);
663+ ptr+= tag_name_length;
664+
665+ memcpy (ptr, source_.get_current (), tag_value_length);
666+ ptr+= tag_value_length;
667+
668+ return ptr;
669+ }
670+
671+
655672// process NAME, either issuer or subject
656673void CertDecoder::GetName (NameType nt)
657674{
658675 if (source_.GetError ().What ()) return ;
659676
660677 SHA sha;
661678 word32 length = GetSequence (); // length of all distinguished names
662- assert (length < ASN_NAME_MAX);
679+
680+ if (length >= ASN_NAME_MAX)
681+ goto err;
663682 length += source_.get_index ();
664683
665- char * ptr = (nt == ISSUER) ? issuer_ : subject_;
666- word32 idx = 0 ;
684+ char *ptr, *buf_end;
685+
686+ if (nt == ISSUER) {
687+ ptr= issuer_;
688+ buf_end= ptr + sizeof (issuer_) - 1 ; // 1 byte for trailing 0
689+ }
690+ else {
691+ ptr= subject_;
692+ buf_end= ptr + sizeof (subject_) - 1 ; // 1 byte for trailing 0
693+ }
667694
668695 while (source_.get_index () < length) {
669696 GetSet ();
@@ -685,47 +712,36 @@ void CertDecoder::GetName(NameType nt)
685712 byte id = source_.next ();
686713 b = source_.next (); // strType
687714 word32 strLen = GetLength (source_);
688- bool copy = false ;
689715
690- if (id == COMMON_NAME) {
691- memcpy (&ptr[idx], " /CN=" , 4 );
692- idx += 4 ;
693- copy = true ;
694- }
695- else if (id == SUR_NAME) {
696- memcpy (&ptr[idx], " /SN=" , 4 );
697- idx += 4 ;
698- copy = true ;
699- }
700- else if (id == COUNTRY_NAME) {
701- memcpy (&ptr[idx], " /C=" , 3 );
702- idx += 3 ;
703- copy = true ;
704- }
705- else if (id == LOCALITY_NAME) {
706- memcpy (&ptr[idx], " /L=" , 3 );
707- idx += 3 ;
708- copy = true ;
709- }
710- else if (id == STATE_NAME) {
711- memcpy (&ptr[idx], " /ST=" , 4 );
712- idx += 4 ;
713- copy = true ;
714- }
715- else if (id == ORG_NAME) {
716- memcpy (&ptr[idx], " /O=" , 3 );
717- idx += 3 ;
718- copy = true ;
719- }
720- else if (id == ORGUNIT_NAME) {
721- memcpy (&ptr[idx], " /OU=" , 4 );
722- idx += 4 ;
723- copy = true ;
724- }
725-
726- if (copy) {
727- memcpy (&ptr[idx], source_.get_current (), strLen);
728- idx += strLen;
716+ switch (id) {
717+ case COMMON_NAME:
718+ if (!(ptr= AddTag (ptr, buf_end, " /CN=" , 4 , strLen)))
719+ goto err;
720+ break ;
721+ case SUR_NAME:
722+ if (!(ptr= AddTag (ptr, buf_end, " /SN=" , 4 , strLen)))
723+ goto err;
724+ break ;
725+ case COUNTRY_NAME:
726+ if (!(ptr= AddTag (ptr, buf_end, " /C=" , 3 , strLen)))
727+ goto err;
728+ break ;
729+ case LOCALITY_NAME:
730+ if (!(ptr= AddTag (ptr, buf_end, " /L=" , 3 , strLen)))
731+ goto err;
732+ break ;
733+ case STATE_NAME:
734+ if (!(ptr= AddTag (ptr, buf_end, " /ST=" , 4 , strLen)))
735+ goto err;
736+ break ;
737+ case ORG_NAME:
738+ if (!(ptr= AddTag (ptr, buf_end, " /O=" , 3 , strLen)))
739+ goto err;
740+ break ;
741+ case ORGUNIT_NAME:
742+ if (!(ptr= AddTag (ptr, buf_end, " /OU=" , 4 , strLen)))
743+ goto err;
744+ break ;
729745 }
730746
731747 sha.Update (source_.get_current (), strLen);
@@ -739,23 +755,20 @@ void CertDecoder::GetName(NameType nt)
739755 source_.advance (oidSz + 1 );
740756 word32 length = GetLength (source_);
741757
742- if (email) {
743- memcpy (&ptr[idx], " /emailAddress=" , 14 );
744- idx += 14 ;
745-
746- memcpy (&ptr[idx], source_.get_current (), length);
747- idx += length;
748- }
758+ if (email && !(ptr= AddTag (ptr, buf_end, " /emailAddress=" , 14 , length)))
759+ goto err;
749760
750761 source_.advance (length);
751762 }
752763 }
753- ptr[idx++] = 0 ;
764+ * ptr= 0 ;
754765
755- if (nt == ISSUER)
756- sha.Final (issuerHash_);
757- else
758- sha.Final (subjectHash_);
766+ sha.Final (nt == ISSUER ? issuerHash_ : subjectHash_);
767+
768+ return ;
769+
770+ err:
771+ source_.SetError (CONTENT_E);
759772}
760773
761774
0 commit comments