Name.cpp

Go to the documentation of this file.
00001 
00009 #include "Name.h"
00010 #include "Buffer.h"
00011 #include "ASN1Helper.h"
00012 #include "PKIX1Explicit88.h"
00013 #include "ToolkitUtils.h"
00014 #include "OID.h"
00015 #include "DistributionPointName.h"
00016 
00018 
00019 //NOTE - this definition is also copied into DistributionPointName.cpp to help with relToIssuer processing
00020 struct CPKIFNameImpl
00021 {
00022     CACX509V3Name* m_name;
00023     CPKIFStringPtr m_string;
00024     CPKIFBufferPtr m_encodedName; //added 8/26/2004
00025 };
00026 
00028 
00036 CPKIFName::CPKIFName()
00037 :m_impl(new CPKIFNameImpl)
00038 {
00039     LOG_STRING_DEBUG("CPKIFName::CPKIFName()", TOOLKIT_X509_ASN, 0, this);
00040 
00041     m_impl->m_name = NULL;
00042 }
00053 //CPKIFName::CPKIFName(
00054 //  //![in] Reference to a CACX509V3Name structure containing information used to populate an instance of CPKIFName              
00055 //  const CACX509V3Name& name)
00056 //  :m_impl(new CPKIFNameImpl)
00057 //{
00058 //  LOG_STRING_DEBUG("CPKIFName::CPKIFName(const CACX509V3Name&)", TOOLKIT_X509_ASN, 0, this);
00059 //
00060 //  //if the name is empty set the m_impl->m_name to NULL and return
00061 //  if(NULL == name.u.rdnSequence || 0 == name.t)
00062 //  {
00063 //      m_impl->m_name = NULL;
00064 //      return;
00065 //  }
00066 //
00067 //  //otherwise - create a copy of the name structure
00068 //  m_impl->m_name = new CACX509V3Name;
00069 //  m_impl->m_name->t = name.t;
00070 //
00071 //  m_impl->m_name->u.rdnSequence = new CACX509V3RDNSequence;
00072 //  m_impl->m_name->u.rdnSequence->head = NULL; m_impl->m_name->u.rdnSequence->tail = NULL; //added this line 4/28/2004
00073 //  m_impl->m_name->u.rdnSequence->count = 0;
00074 //
00075 //  DListNode* cur = NULL, *cur2 = name.u.rdnSequence->head;
00076 //  ASN1OpenType* tmp = NULL, *tmp2 = NULL;
00077 //  
00078 //  //iterate over all of the RDN elements in the name passed as a parameter
00079 //  for(unsigned int ii = 0; ii < name.u.rdnSequence->count; ++ii)
00080 //  {
00081 //      if(NULL == cur)
00082 //      {
00083 //          NEW_NODE(cur)
00084 //      }
00085 //      else
00086 //      {
00087 //          NEW_NEXT_AND_ADVANCE(cur)
00088 //      }
00089 //
00090 //      //create an ASN1OpenType to hold the data
00091 //      //use tmp2 as a temporary pointer to the actual value to copy
00092 //      tmp = new ASN1OpenType;
00093 //      tmp2 = (ASN1OpenType*)cur2->data;
00094 //      
00095 //      //save the length, allocate a buffer and copy the data
00096 //      //throw bad_alloc
00097 //      tmp->numocts = tmp2->numocts;
00098 //      tmp->data = new unsigned char[tmp->numocts];
00099 //      memcpy((void*)tmp->data, tmp2->data, tmp->numocts);
00100 //
00101 //      cur->data = tmp;
00102 //      cur2 = cur2->next;
00103 //
00104 //      //if(0 == m_impl->m_name->u.rdnSequence->count)
00105 //      
00106 //      //CHANGED FROM ABOVE 4/28/2004
00107 //      if(0 == m_impl->m_name->u.rdnSequence->head)
00108 //      {
00109 //          m_impl->m_name->u.rdnSequence->head = cur;
00110 //          m_impl->m_name->u.rdnSequence->tail = cur;
00111 //      }
00112 //      else
00113 //          m_impl->m_name->u.rdnSequence->tail = cur;
00114 //      ++m_impl->m_name->u.rdnSequence->count;
00115 //  }
00116 CPKIFName::CPKIFName(
00118     const CPKIFBufferPtr& name)
00119     :m_impl(new CPKIFNameImpl)
00120 {
00121     LOG_STRING_DEBUG("CPKIFName::CPKIFName(const CACX509V3Name&)", TOOLKIT_X509_ASN, 0, this);
00122 
00123 
00124     CACASNWRAPPER_CREATE(CACX509V3Name, objPDU);
00125     objPDU.Decode(name->GetBuffer(), name->GetLength());
00126 
00127 
00128     //if the name is empty set the m_impl->m_name to NULL and return
00129     if(NULL == objPDU->u.rdnSequence || 0 == objPDU->t)
00130     {
00131         m_impl->m_name = NULL;
00132         return;
00133     }
00134 
00135     //otherwise - create a copy of the name structure
00136     m_impl->m_name = new CACX509V3Name;
00137     m_impl->m_name->t = objPDU->t;
00138 
00139     m_impl->m_name->u.rdnSequence = new CACX509V3RDNSequence;
00140     m_impl->m_name->u.rdnSequence->head = NULL; m_impl->m_name->u.rdnSequence->tail = NULL; //added this line 4/28/2004
00141     m_impl->m_name->u.rdnSequence->count = 0;
00142 
00143     DListNode* cur = NULL, *cur2 = objPDU->u.rdnSequence->head;
00144     ASN1OpenType* tmp = NULL, *tmp2 = NULL;
00145     
00146     //iterate over all of the RDN elements in the name passed as a parameter
00147     for(unsigned int ii = 0; ii < objPDU->u.rdnSequence->count; ++ii)
00148     {
00149         if(NULL == cur)
00150         {
00151             NEW_NODE(cur)
00152         }
00153         else
00154         {
00155             NEW_NEXT_AND_ADVANCE(cur)
00156         }
00157 
00158         //create an ASN1OpenType to hold the data
00159         //use tmp2 as a temporary pointer to the actual value to copy
00160         tmp = new ASN1OpenType;
00161         tmp2 = (ASN1OpenType*)cur2->data;
00162         
00163         //save the length, allocate a buffer and copy the data
00164         //throw bad_alloc
00165         tmp->numocts = tmp2->numocts;
00166         tmp->data = new unsigned char[tmp->numocts];
00167         memcpy((void*)tmp->data, tmp2->data, tmp->numocts);
00168 
00169         cur->data = tmp;
00170         cur2 = cur2->next;
00171 
00172         //if(0 == m_impl->m_name->u.rdnSequence->count)
00173         
00174         //CHANGED FROM ABOVE 4/28/2004
00175         if(0 == m_impl->m_name->u.rdnSequence->head)
00176         {
00177             m_impl->m_name->u.rdnSequence->head = cur;
00178             m_impl->m_name->u.rdnSequence->tail = cur;
00179         }
00180         else
00181             m_impl->m_name->u.rdnSequence->tail = cur;
00182         ++m_impl->m_name->u.rdnSequence->count;
00183     }
00184 }
00185 //}
00193 CPKIFName::~CPKIFName()
00194 {
00195     LOG_STRING_DEBUG("CPKIFName::~CPKIFName()", TOOLKIT_X509_ASN, 0, this);
00196     if(m_impl) {
00197         if(NULL != m_impl->m_name)
00198         {
00199             DListNode* cur = m_impl->m_name->u.rdnSequence->head, *tmpCur = NULL;
00200             ASN1OpenType* tmp = NULL;
00201             for(unsigned int ii = 0; ii < m_impl->m_name->u.rdnSequence->count; ++ii)
00202             {
00203                 tmp = (ASN1OpenType*)cur->data;
00204                 delete[] tmp->data;
00205                 delete tmp;
00206 
00207                 tmpCur = cur->next;
00208                 delete cur;
00209 
00210                 cur = tmpCur;
00211             }
00212 
00213             delete m_impl->m_name->u.rdnSequence; m_impl->m_name->u.rdnSequence = NULL;
00214             delete m_impl->m_name; m_impl->m_name = NULL;
00215         }
00216         delete m_impl;
00217         m_impl = 0;
00218     }
00219 }
00228 CPKIFBufferPtr CPKIFName::Encoded()
00229 {
00230     LOG_STRING_DEBUG("CPKIFName::Encoded()", TOOLKIT_X509_ASN, 0, this);
00231     
00232     if(NULL == m_impl->m_name)
00233     {
00234         CPKIFBufferPtr tmp;
00235         return tmp;
00236     }
00237     else
00238     {
00239         //added m_encodedName stuff 8/26/2004
00240         if(m_impl->m_encodedName == (CPKIFBuffer*)NULL)
00241         {
00242             CACASNWRAPPER_CREATE(CACX509V3Name, objPDU);
00243             ASN1OpenType* data1 = objPDU.Encode(m_impl->m_name);
00244             CPKIFBufferPtr tmp;
00245             if (data1 != NULL)
00246             {
00247                  tmp = CPKIFBufferPtr(new CPKIFBuffer(data1->data, data1->numocts));
00248                 delete data1;
00249             }
00250             m_impl->m_encodedName = tmp;
00251             return tmp;
00252         }
00253         else
00254             return m_impl->m_encodedName;
00255     }
00256 }
00266 //CACX509V3Name* CPKIFName::rawName() 
00267 //{
00268 //  LOG_STRING_DEBUG("CPKIFName::rawName()", TOOLKIT_X509_ASN, 0, this);
00269 //  return m_impl->m_name;
00270 //}
00271 CPKIFBufferPtr CPKIFName::rawName() 
00272 {
00273     LOG_STRING_DEBUG("CPKIFName::rawName()", TOOLKIT_X509_ASN, 0, this);
00274 
00275     CACASNWRAPPER_CREATE(CACX509V3Name, objPDU2);
00276     ASN1OpenType* data1 = objPDU2.Encode(m_impl->m_name);
00277 
00278     CPKIFBufferPtr tmp(new CPKIFBuffer(data1->data, data1->numocts));
00279 
00280     if(data1 != NULL)
00281         delete data1;
00282 
00283     return tmp;
00284 }
00285 
00286 CPKIFOIDPtr g_oidCN(new CPKIFOID("2.5.4.3"));
00287 CPKIFOIDPtr g_oidC(new CPKIFOID("2.5.4.6"));
00288 CPKIFOIDPtr g_oidO(new CPKIFOID("2.5.4.10"));
00289 CPKIFOIDPtr g_oidOU(new CPKIFOID("2.5.4.11"));
00299 bool FindAttributeName(
00301     const CPKIFOIDPtr& oid,
00303     char* oidBuf)
00304 {
00305     //NOTE: All string literals must be no greater than MAXOID in size.
00306 
00307     if(*oid == *g_oidCN)
00308         strcpy(oidBuf, "cn");
00309     else if(*oid == *g_oidC)
00310         strcpy(oidBuf, "c");
00311     else if(*oid == *g_oidO)
00312         strcpy(oidBuf, "o");
00313     else if(*oid == *g_oidOU)
00314         strcpy(oidBuf, "ou");
00315     else if(*oid == "2.5.4.7")
00316         strcpy(oidBuf, "l");
00317     else if(*oid == "1.2.840.113549.1.9.1")
00318         strcpy(oidBuf, "e"); //changed from emailAddress - 02/18/2003 CRW
00319     else if(*oid == "2.5.4.4")
00320         strcpy(oidBuf, "sn");
00321     else if(*oid == "2.5.4.5")
00322         strcpy(oidBuf, "serialNumber");
00323     else if(*oid == "2.5.4.8")
00324         strcpy(oidBuf, "st"); //changed 7/18/2003
00325     else if(*oid == "2.5.4.9")
00326         strcpy(oidBuf, "streetAddress");
00327     else if(*oid == "2.5.4.12")
00328         strcpy(oidBuf, "title");
00329     else if(*oid == "2.5.4.46") //added following items 7/18/2003
00330         strcpy(oidBuf, "dnQualifier");
00331     else if(*oid == "0.9.2342.19200300.100.1.25")
00332         strcpy(oidBuf, "dc");
00333     else if(*oid == "2.5.4.7")
00334         strcpy(oidBuf, "l");
00335     else if(*oid == "2.5.4.42")
00336         strcpy(oidBuf, "givenName");
00337     else if(*oid == "2.5.4.43")
00338         strcpy(oidBuf, "initials");
00339     else if(*oid == "2.5.4.12")
00340         strcpy(oidBuf, "title");
00341     else if(*oid == "2.5.4.44")
00342         strcpy(oidBuf, "generationQualifier");
00343     else
00344         return false;
00345 
00346     return true;
00347 }
00359 const char* CPKIFName::ToString()
00360 {
00361     LOG_STRING_DEBUG("CPKIFName::string()", TOOLKIT_X509_ASN, 0, this);
00362     if(m_impl->m_string != NULL)
00363         return m_impl->m_string->c_str();
00364 
00365     std::string* s = new std::string;
00366     CPKIFStringPtr tmpStr(s);
00367 
00368     //iterate over all RDNs and build string
00369     DListNode* cur = m_impl->m_name->u.rdnSequence->tail;
00370     for(unsigned int ii = 0; ii < m_impl->m_name->u.rdnSequence->count; ++ii)
00371     {
00372         CACASNWRAPPER_CREATE(CACX509V3RelativeDistinguishedName, tmpPDU);
00373         CACX509V3RelativeDistinguishedName* tmpAttr = tmpPDU.Decode(*(ASN1OpenType*)cur->data);
00374 
00375         if(!tmpStr->empty())
00376             tmpStr->append(",");
00377 
00378         DListNode* curMultiRDN = tmpAttr->head;
00379         while(NULL != curMultiRDN)
00380         {
00381             CACX509V3AttributeTypeAndValue* attr99 = (CACX509V3AttributeTypeAndValue*)curMultiRDN->data;
00382 
00383             CACASNWRAPPER_CREATE(CACX509V3CACDirectoryString, objPDU3);
00384 
00385             CPKIFOIDPtr oid(new CPKIFOID(attr99->type.subid, attr99->type.numids));
00386             char oidBuf[MAXOID];
00387             if(FindAttributeName(oid, oidBuf))
00388                 tmpStr->append(oidBuf);
00389             else
00390                 tmpStr->append(oid->ToString());
00391             tmpStr->append("=");
00392 
00393             //added support for non-printable strings 12/9/2003
00394             CACX509V3CACDirectoryString* ds = NULL;
00395             try
00396             {
00397                 ds = objPDU3.Decode(attr99->value);
00398             }
00399             catch(...)
00400             {
00401             }
00402             if(ds)
00403             {
00404                 switch(ds->t)
00405                 {
00406                 case 1:
00407                     if(0 != strstr(ds->u.utf8String, ",") && 0 == strstr(ds->u.utf8String, "\""))
00408                     {
00409                         tmpStr->append("\"");
00410                         tmpStr->append(ds->u.utf8String);
00411                         tmpStr->append("\"");
00412                     }
00413                     else
00414                     {
00415                         tmpStr->append(ds->u.utf8String);
00416                     }
00417                     break;
00418                 case 2:
00419                     if(0 != strstr(ds->u.printableString, ",") && 0 == strstr(ds->u.printableString, "\""))
00420                     {
00421                         tmpStr->append("\"");
00422                         tmpStr->append(ds->u.printableString);
00423                         tmpStr->append("\"");
00424                     }
00425                     else
00426                     {
00427                         tmpStr->append(ds->u.printableString);
00428                     }
00429 
00430                     break;
00431                 case 3:
00432                     if(0 != strstr(ds->u.teletexString, ",") && 0 == strstr(ds->u.teletexString, "\""))
00433                     {
00434                         tmpStr->append("\"");
00435                         tmpStr->append(ds->u.teletexString);
00436                         tmpStr->append("\"");
00437                     }
00438                     else
00439                     {
00440                         tmpStr->append(ds->u.teletexString);
00441                     }
00442                     break;
00443                 case 4:
00444                     if(0 != strstr(ds->u.ia5String, ",") && 0 == strstr(ds->u.ia5String, "\""))
00445                     {
00446                         tmpStr->append("\"");
00447                         tmpStr->append(ds->u.ia5String);
00448                         tmpStr->append("\"");
00449                     }
00450                     else
00451                     {
00452                         tmpStr->append(ds->u.ia5String);
00453                     }
00454                     break;
00455                 case 5:
00456                     if(0 != strstr(ds->u.generalString, ",") && 0 == strstr(ds->u.generalString, "\""))
00457                     {
00458                         tmpStr->append("\"");
00459                         tmpStr->append(ds->u.generalString);
00460                         tmpStr->append("\"");
00461                     }
00462                     else
00463                     {
00464                         tmpStr->append(ds->u.generalString);
00465                     }
00466                     break;
00467                 case 6://XXX-DEFER - string conversion for BMP and universal strings (added 6 and 7 semi-support 5/26/2004)
00468                     {
00469                     int tmpLen = ds->u.universalString.nchars + 1;
00470                     char* p = new char[tmpLen];
00471                     char* tmpP = p;
00472                     const char* tmpConstP = ucsToCStr(&ds->u.universalString, tmpP, tmpLen);
00473                     tmpStr->append(tmpConstP);
00474                     delete[] tmpP;
00475                     break;
00476                     }
00477                 case 7:
00478                     {
00479                     int tmpLen = ds->u.bmpString.nchars + 1;
00480                     char* p = new char[tmpLen];
00481                     char* tmpP = p;
00482                     const char* tmpConstP = bmpToCStr(&ds->u.bmpString, tmpP, tmpLen);
00483                     tmpStr->append(tmpConstP);
00484                     delete[] tmpP;
00485                     break;
00486                     }
00487                 default:
00488                     throw CPKIFException(TOOLKIT_ASN, -1, "Unsupported name form for string conversion");
00489                 }
00490             }
00491             else
00492             {
00493                 //case for funky DNs that do not have directory strings
00494                 char* tmpUnusualRdnValue = new char[(attr99->value.numocts*2) + 1];
00495                 btoa((const char*)attr99->value.data, tmpUnusualRdnValue, attr99->value.numocts);
00496                 tmpStr->append(tmpUnusualRdnValue);
00497                 delete[] tmpUnusualRdnValue;
00498             }
00499 
00500             curMultiRDN = curMultiRDN->next;
00501             if(NULL != curMultiRDN)
00502                 tmpStr->append("+");
00503         }
00504 
00505         cur= cur->prev; 
00506     }
00507 
00508     m_impl->m_string = tmpStr;
00509     return m_impl->m_string->c_str();
00510 } 
00511 
00512 //
00513 // Character type table for 0-0x7F range
00514 //
00515 #define _UPPER      0x1  // upper case letter
00516 #define _LOWER      0x2  // lower case letter
00517 #define _DIGIT      0x4  // digit[0-9]
00518 #define _SPACE      0x8  // tab, carriage return, newline, vertical tab or form feed
00519 #define _PUNCT      0x10 // punctuation character
00520 #define _CONTROL    0x20 // control character
00521 #define _BLANK      0x40 // space char
00522 #define _HEX        0x80 // hexadecimal digit
00523 
00524 char allSpaces[] = {0x09,0x0A,0x0B,0x0C,0x0D,0x20};
00525 const int CharTableSize = 128;
00526 static unsigned short CharTable[CharTableSize] = {
00527         _CONTROL,               // 00 (NUL)
00528         _CONTROL,               // 01 (SOH)
00529         _CONTROL,               // 02 (STX)
00530         _CONTROL,               // 03 (ETX)
00531         _CONTROL,               // 04 (EOT)
00532         _CONTROL,               // 05 (ENQ)
00533         _CONTROL,               // 06 (ACK)
00534         _CONTROL,               // 07 (BEL)
00535         _CONTROL,               // 08 (BS)
00536         _SPACE+_CONTROL,        // 09 (HT)
00537         _SPACE+_CONTROL,        // 0A (LF)
00538         _SPACE+_CONTROL,        // 0B (VT)
00539         _SPACE+_CONTROL,        // 0C (FF)
00540         _SPACE+_CONTROL,        // 0D (CR)
00541         _CONTROL,               // 0E (SI)
00542         _CONTROL,               // 0F (SO)
00543         _CONTROL,               // 10 (DLE)
00544         _CONTROL,               // 11 (DC1)
00545         _CONTROL,               // 12 (DC2)
00546         _CONTROL,               // 13 (DC3)
00547         _CONTROL,               // 14 (DC4)
00548         _CONTROL,               // 15 (NAK)
00549         _CONTROL,               // 16 (SYN)
00550         _CONTROL,               // 17 (ETB)
00551         _CONTROL,               // 18 (CAN)
00552         _CONTROL,               // 19 (EM)
00553         _CONTROL,               // 1A (SUB)
00554         _CONTROL,               // 1B (ESC)
00555         _CONTROL,               // 1C (FS)
00556         _CONTROL,               // 1D (GS)
00557         _CONTROL,               // 1E (RS)
00558         _CONTROL,               // 1F (US)
00559         _SPACE+_BLANK,          // 20 SPACE
00560         _PUNCT,                 // 21 !
00561         _PUNCT,                 // 22 "
00562         _PUNCT,                 // 23 #
00563         _PUNCT,                 // 24 $
00564         _PUNCT,                 // 25 %
00565         _PUNCT,                 // 26 &
00566         _PUNCT,                 // 27 '
00567         _PUNCT,                 // 28 (
00568         _PUNCT,                 // 29 )
00569         _PUNCT,                 // 2A *
00570         _PUNCT,                 // 2B +
00571         _PUNCT,                 // 2C ,
00572         _PUNCT,                 // 2D -
00573         _PUNCT,                 // 2E .
00574         _PUNCT,                 // 2F /
00575         _DIGIT+_HEX,            // 30 0
00576         _DIGIT+_HEX,            // 31 1
00577         _DIGIT+_HEX,            // 32 2
00578         _DIGIT+_HEX,            // 33 3
00579         _DIGIT+_HEX,            // 34 4
00580         _DIGIT+_HEX,            // 35 5
00581         _DIGIT+_HEX,            // 36 6
00582         _DIGIT+_HEX,            // 37 7
00583         _DIGIT+_HEX,            // 38 8
00584         _DIGIT+_HEX,            // 39 9
00585         _PUNCT,                 // 3A :
00586         _PUNCT,                 // 3B ;
00587         _PUNCT,                 // 3C <
00588         _PUNCT,                 // 3D =
00589         _PUNCT,                 // 3E >
00590         _PUNCT,                 // 3F ?
00591         _PUNCT,                 // 40 @
00592         _UPPER+_HEX,            // 41 A
00593         _UPPER+_HEX,            // 42 B
00594         _UPPER+_HEX,            // 43 C
00595         _UPPER+_HEX,            // 44 D
00596         _UPPER+_HEX,            // 45 E
00597         _UPPER+_HEX,            // 46 F
00598         _UPPER,                 // 47 G
00599         _UPPER,                 // 48 H
00600         _UPPER,                 // 49 I
00601         _UPPER,                 // 4A J
00602         _UPPER,                 // 4B K
00603         _UPPER,                 // 4C L
00604         _UPPER,                 // 4D M
00605         _UPPER,                 // 4E N
00606         _UPPER,                 // 4F O
00607         _UPPER,                 // 50 P
00608         _UPPER,                 // 51 Q
00609         _UPPER,                 // 52 R
00610         _UPPER,                 // 53 S
00611         _UPPER,                 // 54 T
00612         _UPPER,                 // 55 U
00613         _UPPER,                 // 56 V
00614         _UPPER,                 // 57 W
00615         _UPPER,                 // 58 X
00616         _UPPER,                 // 59 Y
00617         _UPPER,                 // 5A Z
00618         _PUNCT,                 // 5B [
00619         _PUNCT,                 // 5C \ (do not end the line with back slash)
00620         _PUNCT,                 // 5D ]
00621         _PUNCT,                 // 5E ^
00622         _PUNCT,                 // 5F _
00623         _PUNCT,                 // 60 `
00624         _LOWER+_HEX,            // 61 a
00625         _LOWER+_HEX,            // 62 b
00626         _LOWER+_HEX,            // 63 c
00627         _LOWER+_HEX,            // 64 d
00628         _LOWER+_HEX,            // 65 e
00629         _LOWER+_HEX,            // 66 f
00630         _LOWER,                 // 67 g
00631         _LOWER,                 // 68 h
00632         _LOWER,                 // 69 i
00633         _LOWER,                 // 6A j
00634         _LOWER,                 // 6B k
00635         _LOWER,                 // 6C l
00636         _LOWER,                 // 6D m
00637         _LOWER,                 // 6E n
00638         _LOWER,                 // 6F o
00639         _LOWER,                 // 70 p
00640         _LOWER,                 // 71 q
00641         _LOWER,                 // 72 r
00642         _LOWER,                 // 73 s
00643         _LOWER,                 // 74 t
00644         _LOWER,                 // 75 u
00645         _LOWER,                 // 76 v
00646         _LOWER,                 // 77 w
00647         _LOWER,                 // 78 x
00648         _LOWER,                 // 79 y
00649         _LOWER,                 // 7A z
00650         _PUNCT,                 // 7B {
00651         _PUNCT,                 // 7C |
00652         _PUNCT,                 // 7D }
00653         _PUNCT,                 // 7E ~
00654         _CONTROL                // 7F (DEL)
00655         // and the rest is filled with 0s...
00656 };
00664 bool CharIsSpace(
00666     char c)
00667 {
00668     if( c < CharTableSize )
00669     {
00670         return ( 0 != (CharTable[c] & _SPACE) );
00671     }
00672     
00673     return false;
00674 }
00675 
00676 // trim_right() family.
00684 inline std::string trim_right ( 
00686     const std::string & source ,
00688     const std::string & t = allSpaces )
00689 {
00690        std::string str = source;
00691        return str.erase ( str.find_last_not_of ( t ) + 1 ) ; 
00692 }
00693 
00694 // trim_left() family.
00702 inline std::string trim_left (
00704     const std::string & source , 
00706     const std::string & t = allSpaces )
00707 { 
00708        std::string str = source;
00709        return str.erase ( 0 , source.find_first_not_of ( t ) ) ; 
00710 }
00711 
00712 // trim() family.
00720 inline std::string trim (
00722     const std::string & source ,
00724     const std::string & t = allSpaces )
00725 { 
00726        std::string str = source;
00727        return trim_left ( trim_right ( str , t ) , t ) ; 
00728 }
00736 bool CompareRDNStrings(
00738     const char* lhsStr, 
00740     const char* rhsStr)
00741 {
00742     //build temp strings of each minus extra white space
00743     //std::string lhsTmp;
00744     //std::string rhsTmp;
00745 
00746     size_t len1 = strlen(lhsStr);
00747     size_t len2 = strlen(rhsStr);
00748     size_t count1 = 0;
00749     size_t count2 = 0;
00750 
00751     while(count1 < len1 && CharIsSpace(lhsStr[count1]))
00752             ++count1;
00753     while(count2 < len2 && CharIsSpace(rhsStr[count2]))
00754             ++count2;
00755 
00756     do
00757     {
00758         //if we've reached the end of both string - break and declare success
00759         if(count1 >= len1 && count2 >= len2)
00760             break;
00761         else if(count1 >= len1 || count2 >= len2) //one ended - not the other - no match
00762             return false;
00763         
00764         const char* t1 = &lhsStr[count1];
00765         const char* t2 = &rhsStr[count2];
00766         //reviewed 4/24 - length checks already performed
00767         if(0 == strnicmp(t1, t2, 1))
00768         {
00769             ++count1;
00770             ++count2;
00771         }
00772         else 
00773             return false;
00774 
00775         if( CharIsSpace(lhsStr[count1]))
00776         {
00777             while(count1 < len1 && (CharIsSpace(lhsStr[count1+1]) || count1+1 >= len1))
00778                 ++count1;
00779             
00780         }
00781         if( CharIsSpace(rhsStr[count2]))
00782         {
00783             while(count2 < len2 && (CharIsSpace(rhsStr[count2+1]) || count2+1 >= len2))
00784                 ++count2;
00785         }
00786 
00787 
00788     }while(1);
00789     /*
00790     int len = strlen(lhsStr);
00791     int spaceCount = 0;
00792     for(int ii = 0; ii < len; ++ii)
00793     {
00794         if( CharIsSpace(lhsStr[ii])) 
00795             ++spaceCount;
00796         else 
00797             spaceCount = 0;
00798         
00799         if( spaceCount <= 1) {
00800             lhsTmp.push_back( lhsStr[ii] );
00801         }
00802     }
00803 
00804     len = strlen(rhsStr);
00805     for(ii = 0; ii < len; ++ii)
00806     {
00807         if( CharIsSpace(rhsStr[ii])) 
00808             ++spaceCount;
00809         else 
00810             spaceCount = 0;
00811         
00812         if( spaceCount <= 1) {
00813             rhsTmp.push_back( rhsStr[ii] );
00814         }
00815     }
00816 
00817     //remove any leading or trailing white space
00818     lhsTmp = trim(lhsTmp);
00819     rhsTmp = trim(rhsTmp);
00820 
00821     if(0 == stricmp(lhsTmp.c_str(), rhsTmp.c_str()))
00822         return true;
00823     else
00824         return false;*/
00825 
00826     return true;
00827 }
00828 
00829 //added this to support reduction of OID conversion in RDNsMatch - 8/26/2004
00837 bool CompareASN1OIDs(
00839     ASN1OBJID* lhs,
00841     ASN1OBJID* rhs)
00842 {
00843     if(lhs->numids != rhs->numids)
00844         return false;
00845 
00846     //changed to start search at end of OID
00847     for(int ii = lhs->numids - 1; ii >= 0; --ii) 
00848         if(lhs->subid[ii] != rhs->subid[ii])
00849             return false;
00850 
00851     return true;
00852 }
00860 bool RDNsMatch(
00862     CACX509V3RelativeDistinguishedName* lhs,
00864     CACX509V3RelativeDistinguishedName* rhs)
00865 {
00866     if(lhs->count != rhs->count)
00867         return false;
00868 
00869     DListNode* curLHS = lhs->head;
00870     DListNode* curRHS = rhs->head;
00871     for(unsigned int ii = 0; ii < lhs->count; ++ii)
00872     {
00873         CACX509V3AttributeTypeAndValue* dataLHS = (CACX509V3AttributeTypeAndValue*)curLHS->data;
00874         CACX509V3AttributeTypeAndValue* dataRHS = (CACX509V3AttributeTypeAndValue*)curRHS->data;
00875 
00876         //eliminate OID conversion - 8/26/2004
00877         //CPKIFOIDPtr lhsOID(new CPKIFOID(dataLHS->type));
00878         //CPKIFOIDPtr rhsOID(new CPKIFOID(dataRHS->type));
00879         //if(!(*lhsOID == *rhsOID))
00880         //  return false;
00881 
00882         if(!CompareASN1OIDs(&dataLHS->type, &dataRHS->type))
00883             return false;
00884 
00885         //added favor binary compare - 8/26/2004
00886         if(dataLHS->value.numocts != dataRHS->value.numocts ||
00887             0 != memcmp(dataLHS->value.data, dataRHS->value.data, dataLHS->value.numocts))
00888         {
00889             CACASNWRAPPER_CREATE(CACX509V3CACDirectoryString, objPDULHS);
00890             CACX509V3CACDirectoryString* dsLHS = objPDULHS.Decode(dataLHS->value);
00891 
00892             CACASNWRAPPER_CREATE(CACX509V3CACDirectoryString, objPDURHS);
00893             CACX509V3CACDirectoryString* dsRHS = objPDURHS.Decode(dataRHS->value);
00894 
00895             if(dsLHS->t != dsRHS->t)
00896             {
00897                 //added 12/2/2003 to handle printablestring to utf8 rollover scenarios
00898                 if((dsLHS->t == 1 || dsLHS->t == 2) && (dsRHS->t == 1 || dsRHS->t == 2))
00899                 {
00900                     const char* lhsStr = NULL, *rhsStr = NULL;
00901                     size_t lhsLen = 0, rhsLen = 0;
00902                     if(dsLHS->t == 1)
00903                         lhsStr = dsLHS->u.utf8String;
00904                     else
00905                         lhsStr = dsLHS->u.printableString;
00906                     lhsLen = strlen(lhsStr);
00907                     if(dsRHS->t == 1)
00908                         rhsStr = dsRHS->u.utf8String;
00909                     else
00910                         rhsStr = dsRHS->u.printableString;
00911                     rhsLen = strlen(rhsStr);
00912 
00913                     if(!CompareRDNStrings(lhsStr, rhsStr))
00914                         return false;
00915                 }
00916                 else
00917                     return false;
00918             }
00919             else
00920             {
00921                 const char* lhsStr = NULL, *rhsStr = NULL;
00922                 size_t lhsLen = 0, rhsLen = 0;
00923                 switch(dsLHS->t)
00924                 {
00925                 case 1://UTF8
00926                     lhsStr = dsLHS->u.utf8String; 
00927                     rhsStr = dsRHS->u.utf8String;
00928                     lhsLen = strlen(lhsStr);
00929                     rhsLen = strlen(rhsStr);
00930                     break;
00931                 case 2://PrintableString
00932                     lhsStr = dsLHS->u.printableString;
00933                     rhsStr = dsRHS->u.printableString;
00934                     lhsLen = strlen(lhsStr);
00935                     rhsLen = strlen(rhsStr);
00936                     break;
00937                 case 3://TeletexString
00938                     lhsStr = dsLHS->u.teletexString;
00939                     rhsStr = dsRHS->u.teletexString;
00940                     lhsLen = strlen(lhsStr);
00941                     rhsLen = strlen(rhsStr);
00942                     break;
00943                 case 4://IA5String
00944                     lhsStr = dsLHS->u.ia5String;
00945                     rhsStr = dsRHS->u.ia5String;
00946                     lhsLen = strlen(lhsStr);
00947                     rhsLen = strlen(rhsStr);
00948                     break;
00949                 case 5://GeneralString
00950                     lhsStr = dsLHS->u.generalString;
00951                     rhsStr = dsRHS->u.generalString;
00952                     lhsLen = strlen(lhsStr);
00953                     rhsLen = strlen(rhsStr);
00954                     break;
00955                 case 6://UniversalString
00956                     lhsLen = dsLHS->u.universalString.nchars;
00957                     rhsLen = dsRHS->u.universalString.nchars;
00958                     break;
00959                 case 7://BMPString
00960                     lhsLen = dsLHS->u.bmpString.nchars;
00961                     rhsLen = dsRHS->u.bmpString.nchars;
00962                     break;
00963                 }
00964 
00965                 if(6 != dsLHS->t && 7 != dsLHS->t)
00966                 {
00967                     if(!CompareRDNStrings(lhsStr, rhsStr))
00968                         return false;
00969                 }
00970                 else
00971                 {
00972                     //XXX***case insensitive?
00973                     if(lhsLen != rhsLen)
00974                         return false;
00975                     if(6 == dsLHS->t)
00976                     {
00977                         if(0 != memcmp(dsLHS->u.universalString.data, dsRHS->u.universalString.data, lhsLen))
00978                             return false;
00979                     }
00980                     else
00981                     {
00982                         if(0 != memcmp(dsLHS->u.bmpString.data, dsRHS->u.bmpString.data, lhsLen))
00983                             return false;
00984                     }
00985                 }
00986             }
00987         }//end new condition 8/26/2004
00988         curLHS = curLHS->next; 
00989         curRHS = curRHS->next;
00990     }
00991 
00992     return true;
00993 }
01002 bool CPKIFName::operator==(
01004     const CPKIFName& rhs) const
01005 {
01006     if(NULL == this->m_impl->m_name && NULL == rhs.m_impl->m_name)
01007         return true;
01008 
01009     if(this->m_impl->m_name->u.rdnSequence->count != rhs.m_impl->m_name->u.rdnSequence->count)
01010         return false;
01011 
01012     DListNode* curLHS = this->m_impl->m_name->u.rdnSequence->head;
01013     DListNode* curRHS = rhs.m_impl->m_name->u.rdnSequence->head;
01014     for(unsigned int ii = 0; ii < this->m_impl->m_name->u.rdnSequence->count; ++ii)
01015     {
01016         //added 8/26/2004
01017         ASN1OpenType* lhsP = (ASN1OpenType*)curLHS->data;
01018         ASN1OpenType* rhsP = (ASN1OpenType*)curRHS->data;
01019         if(lhsP->numocts != rhsP->numocts || 0 != memcmp(lhsP->data, rhsP->data, rhsP->numocts))
01020         {
01021             //parse and compare if binary equality fails - 8/26/2004
01022             CACASNWRAPPER_CREATE(CACX509V3RelativeDistinguishedName, tmpPDULHS);
01023             CACX509V3RelativeDistinguishedName* lhs = tmpPDULHS.Decode(*lhsP);
01024 
01025             CACASNWRAPPER_CREATE(CACX509V3RelativeDistinguishedName, tmpPDURHS);
01026             CACX509V3RelativeDistinguishedName* rhs = tmpPDURHS.Decode(*rhsP);
01027 
01028             if(!RDNsMatch(lhs, rhs))
01029                 return false;
01030         }
01031         curLHS = curLHS->next; 
01032         curRHS = curRHS->next;
01033     }
01034 
01035     return true;
01036 }
01037 
01046 bool CPKIFName::DescendedFrom(
01048     const CPKIFName& rhs) const
01049 {
01050     //if descendant has same or fewer rdns then it is not a descendant
01051     if( m_impl->m_name->u.rdnSequence->count >= rhs.m_impl->m_name->u.rdnSequence->count) 
01052         return false;
01053 
01054     DListNode* curLHS = this->m_impl->m_name->u.rdnSequence->head;
01055     DListNode* curRHS = rhs.m_impl->m_name->u.rdnSequence->head;
01056     for(unsigned int ii = 0; ii < this->m_impl->m_name->u.rdnSequence->count; ++ii)
01057     {
01058         CACASNWRAPPER_CREATE(CACX509V3RelativeDistinguishedName, tmpPDULHS);
01059         CACX509V3RelativeDistinguishedName* lhs = tmpPDULHS.Decode(*(ASN1OpenType*)curLHS->data);
01060 
01061         CACASNWRAPPER_CREATE(CACX509V3RelativeDistinguishedName, tmpPDURHS);
01062         CACX509V3RelativeDistinguishedName* rhs = tmpPDURHS.Decode(*(ASN1OpenType*)curRHS->data);
01063 
01064         if(!RDNsMatch(lhs, rhs))
01065             return false;
01066 
01067         curLHS = curLHS->next; 
01068         curRHS = curRHS->next;
01069     }
01070 
01071     return true;
01072 }
01080 int CPKIFName::RDNCount() const
01081 {
01082     if(NULL == m_impl->m_name || NULL == m_impl->m_name->u.rdnSequence)
01083         return 0;
01084     else
01085         return m_impl->m_name->u.rdnSequence->count;
01086 }
01087 
01097 void CPKIFName::GetRDNs(std::vector<std::string>& rdns) const
01098 {
01099     LOG_STRING_DEBUG("CPKIFName::string()", TOOLKIT_X509_ASN, 0, this);
01100 
01101     //iterate over all RDNs and populate vector
01102     DListNode* cur = m_impl->m_name->u.rdnSequence->tail;
01103     for(unsigned int ii = 0; ii < m_impl->m_name->u.rdnSequence->count; ++ii)
01104     {
01105         CACASNWRAPPER_CREATE(CACX509V3RelativeDistinguishedName, tmpPDU);
01106         CACX509V3RelativeDistinguishedName* tmpAttr = tmpPDU.Decode(*(ASN1OpenType*)cur->data);
01107 
01108         std::string rdnString;
01109 
01110         DListNode* curMultiRDN = tmpAttr->head;
01111         while(NULL != curMultiRDN)
01112         {
01113             CACX509V3AttributeTypeAndValue* attr99 = (CACX509V3AttributeTypeAndValue*)curMultiRDN->data;
01114 
01115             CACASNWRAPPER_CREATE(CACX509V3CACDirectoryString, objPDU3);
01116             CACX509V3CACDirectoryString* ds = objPDU3.Decode(attr99->value);
01117 
01118             CPKIFOIDPtr oid(new CPKIFOID(attr99->type.subid, attr99->type.numids));
01119             char oidBuf[MAXOID];
01120             if(FindAttributeName(oid, oidBuf))
01121                 rdnString.append(oidBuf);
01122             else
01123                 rdnString.append(oid->ToString());
01124             rdnString.append("=");
01125 
01126             //added support for non-printable strings 12/9/2003
01127             switch(ds->t)
01128             {
01129             case 1:
01130                 if(0 != strstr(ds->u.utf8String, ","))
01131                     rdnString.append("\"");
01132                 rdnString.append(ds->u.utf8String);
01133                 if(0 != strstr(ds->u.utf8String, ","))
01134                     rdnString.append("\"");
01135                 break;
01136             case 2:
01137                 if(0 != strstr(ds->u.printableString, ","))
01138                     rdnString.append("\"");
01139                 rdnString.append(ds->u.printableString);
01140                 if(0 != strstr(ds->u.printableString, ","))
01141                     rdnString.append("\"");
01142                 break;
01143             case 3:
01144                 if(0 != strstr(ds->u.teletexString, ","))
01145                     rdnString.append("\"");
01146                 rdnString.append(ds->u.teletexString);
01147                 if(0 != strstr(ds->u.teletexString, ","))
01148                     rdnString.append("\"");
01149                 break;
01150             case 4:
01151                 if(0 != strstr(ds->u.ia5String, ","))
01152                     rdnString.append("\"");
01153                 rdnString.append(ds->u.ia5String);
01154                 if(0 != strstr(ds->u.ia5String, ","))
01155                     rdnString.append("\"");
01156                 break;
01157             case 5:
01158                 if(0 != strstr(ds->u.generalString, ","))
01159                     rdnString.append("\"");
01160                 rdnString.append(ds->u.generalString);
01161                 if(0 != strstr(ds->u.generalString, ","))
01162                     rdnString.append("\"");
01163                 break;
01164             case 6://XXX-DEFER - string conversion for BMP and universal strings (added 6 and 7 semi-support 5/26/2004)
01165                 {
01166                 int tmpLen = ds->u.universalString.nchars + 1;
01167                 char* p = new char[tmpLen];
01168                 char* tmpP = p;
01169                 const char* tmpConstP = ucsToCStr(&ds->u.universalString, tmpP, tmpLen);
01170                 rdnString.append(tmpConstP);
01171                 delete[] tmpP;
01172                 break;
01173                 }
01174             case 7:
01175                 {
01176                 int tmpLen = ds->u.bmpString.nchars + 1;
01177                 char* p = new char[tmpLen];
01178                 char* tmpP = p;
01179                 const char* tmpConstP = bmpToCStr(&ds->u.bmpString, tmpP, tmpLen);
01180                 rdnString.append(tmpConstP);
01181                 delete[] tmpP;
01182                 break;
01183                 }
01184             default:
01185                 throw CPKIFException(TOOLKIT_ASN, -1, "Unsupported name form for string conversion");
01186             }
01187 
01188             curMultiRDN = curMultiRDN->next;
01189             if(NULL != curMultiRDN)
01190                 rdnString.append("+");
01191         }
01192 
01193         rdns.push_back(rdnString);
01194         cur= cur->prev; 
01195     }
01196 }
01197 

Generated on Mon Nov 15 11:15:51 2010 for PublicKeyInfrastructureFramework(PKIF) by  doxygen 1.5.6