18 #ifdef USE_CERTIFICATES
28 #define MKDNOID( value ) MKOID( "\x06\x03" value )
41 "c", 1,
"oid.2.5.4.6", 11, 2,
FALSE, FALSE },
43 "l", 1,
"oid.2.5.4.7", 11, 128,
FALSE,
TRUE },
45 "sp", 2,
"oid.2.5.4.8", 11, 128,
FALSE,
TRUE },
52 { 1, MKDNOID(
"\x55\x04\x01" ),
54 { 2, MKDNOID(
"\x55\x04\x02" ),
56 { 3, MKDNOID(
"\x55\x04\x04" ),
58 { 4, MKDNOID(
"\x55\x04\x05" ),
60 { 5, MKDNOID(
"\x55\x04\x09" ),
61 "st", 2,
"oid.2.5.4.9", 11, 128,
FALSE,
FALSE },
62 { 6, MKDNOID(
"\x55\x04\x0C" ),
64 { 7, MKDNOID(
"\x55\x04\x0D" ),
65 "d", 1,
"oid.2.5.4.13", 12, 1024,
FALSE,
FALSE },
66 { 8, MKDNOID(
"\x55\x04\x0E" ),
68 { 9, MKDNOID(
"\x55\x04\x0F" ),
69 "bc", 2,
"oid.2.5.4.15", 12, 128,
FALSE,
FALSE },
70 { 10, MKDNOID(
"\x55\x04\x10" ),
72 { 11, MKDNOID(
"\x55\x04\x11" ),
73 "oid.2.5.4.17", 12, NULL, 0, 40,
FALSE, FALSE },
74 { 12, MKDNOID(
"\x55\x04\x12" ),
75 "oid.2.5.4.18", 12, NULL, 0, 40,
FALSE, FALSE },
76 { 13, MKDNOID(
"\x55\x04\x13" ),
77 "oid.2.5.4.19", 12, NULL, 0, 128,
FALSE, FALSE },
78 { 14, MKDNOID(
"\x55\x04\x14" ),
79 "oid.2.5.4.20", 12, NULL, 0, 32,
FALSE, FALSE },
80 { 15, MKDNOID(
"\x55\x04\x15" ),
81 "oid.2.5.4.21", 12, NULL, 0, 14,
FALSE, FALSE },
82 { 16, MKDNOID(
"\x55\x04\x16" ),
83 "oid.2.5.4.22", 12, NULL, 0, 24,
FALSE, FALSE },
84 { 17, MKDNOID(
"\x55\x04\x17" ),
85 "oid.2.5.4.23", 12, NULL, 0, 32,
FALSE, FALSE },
86 { 18, MKDNOID(
"\x55\x04\x18" ),
87 "oid.2.5.4.24", 12, NULL, 0, 15,
FALSE, FALSE },
88 { 19, MKDNOID(
"\x55\x04\x19" ),
89 "isdn", 4,
"oid.2.5.4.25", 12, 16,
FALSE,
FALSE },
90 { 20, MKDNOID(
"\x55\x04\x1A" ),
92 { 21, MKDNOID(
"\x55\x04\x1B" ),
93 "oid.2.5.4.27", 12, NULL, 0, 128,
FALSE, FALSE },
94 { 22, MKDNOID(
"\x55\x04\x1C" ),
96 { 23, MKDNOID(
"\x55\x04\x1D" ),
98 { 24, MKDNOID(
"\x55\x04\x1E" ),
100 { 25, MKDNOID(
"\x55\x04\x1F" ),
102 { 26, MKDNOID(
"\x55\x04\x20" ),
104 { 27, MKDNOID(
"\x55\x04\x21" ),
106 { 28, MKDNOID(
"\x55\x04\x22" ),
109 { 29, MKDNOID(
"\x55\x04\x29" ),
111 { 30, MKDNOID(
"\x55\x04\x2A" ),
113 { 31, MKDNOID(
"\x55\x04\x2B" ),
115 { 32, MKDNOID(
"\x55\x04\x2C" ),
117 { 33, MKDNOID(
"\x55\x04\x2D" ),
119 { 34, MKDNOID(
"\x55\x04\x2E" ),
122 { 35, MKDNOID(
"\x55\x04\x31" ),
124 { 36, MKDNOID(
"\x55\x04\x32" ),
126 { 37, MKDNOID(
"\x55\x04\x33" ),
129 { 38, MKDNOID(
"\x55\x04\x41" ),
130 "oid.2.5.4.65", 12, NULL, 0, 128,
FALSE, FALSE },
131 { 39, MKDNOID(
"\x55\x04\x42" ),
133 { 40, MKDNOID(
"\x55\x04\x43" ),
136 { 41,
MKOID(
"\x06\x0A\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x01" ),
138 { 42,
MKOID(
"\x06\x0A\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x03" ),
140 { 43,
MKOID(
"\x06\x0A\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19" ),
142 { 44,
MKOID(
"\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" ),
144 { 45,
MKOID(
"\x06\x07\x02\x82\x06\x01\x0A\x07\x14" ),
152 #define xA ( 1 << 0 )
153 #define xB ( 1 << 1 )
154 #define xC ( 1 << 2 )
155 #define xD ( 1 << 3 )
156 #define xE ( 1 << 4 )
157 #define xF ( 1 << 5 )
158 #define xG ( 1 << 6 )
159 #define xH ( 1 << 7 )
160 #define xI ( 1 << 8 )
161 #define xJ ( 1 << 9 )
162 #define xK ( 1 << 10 )
163 #define xL ( 1 << 11 )
164 #define xM ( 1 << 12 )
165 #define xN ( 1 << 13 )
166 #define xO ( 1 << 14 )
167 #define xP ( 1 << 15 )
168 #define xQ ( 1 << 16 )
169 #define xR ( 1 << 17 )
170 #define xS ( 1 << 18 )
171 #define xT ( 1 << 19 )
172 #define xU ( 1 << 20 )
173 #define xV ( 1 << 21 )
174 #define xW ( 1 << 22 )
175 #define xX ( 1 << 23 )
176 #define xY ( 1 << 24 )
177 #define xZ ( 1 << 25 )
182 static const long countryCodes[] = {
184 xD|xE|xF|xG| xI| xL|xM|xN|xO| xQ|xR|xS|xT|xU| xW| xZ,
185 xA|xB| xD|xE|xF|xG|xH|xI|xJ| xM|xN|xO| xR|xS|xT| xV|xW| xY|xZ,
186 xA| xC|xD| xF|xG|xH|xI| xK|xL|xM|xN|xO| xR| xU|xV| xX|xY|xZ,
187 xE| xJ|xK| xM| xO| xZ,
188 xC| xE| xG|xH| xR|xS|xT,
189 xI|xJ|xK| xM| xO| xR,
190 xA|xB| xD|xE|xF| xH|xI| xL|xM|xN| xP|xQ|xR|xS|xT|xU| xW| xY,
191 xK| xM|xN| xR| xT|xU,
192 xD|xE| xL| xN|xO| xQ|xR|xS|xT,
194 xE| xG|xH|xI| xM|xN| xP| xR| xW| xY|xZ,
195 xA|xB|xC| xI| xK| xR|xS|xT|xU|xV| xY,
196 xA| xC|xD| xG|xH| xK|xL|xM|xN|xO|xP|xQ|xR|xS|xT|xU|xV|xW|xX|xY|xZ,
197 xA| xC| xE|xF|xG| xI| xL| xO|xP| xR| xU| xZ,
199 xA| xE|xF|xG|xH| xK|xL|xM|xN| xR|xS|xT| xW| xY,
202 xA|xB|xC|xD|xE| xG|xH|xI|xJ|xK|xL|xM|xN|xO| xR| xT| xV| xY|xZ,
203 xC|xD| xF|xG|xH| xJ|xK|xL|xM|xN|xO| xR| xT| xV|xW| xZ,
204 xA| xG| xM| xS| xY|xZ,
205 xA| xC| xE| xG| xI| xN| xU,
212 const int cc0 = countryCode[ 0 ] -
'A';
213 const int cc1 = countryCode[ 1 ] -
'A';
221 if( cc0 < 0 || cc0 > 25 || cc1 < 0 || cc1 > 25 )
223 return( ( countryCodes[ cc0 ] & ( 1L << cc1 ) ) ?
TRUE :
FALSE );
231 static const MAP_TABLE dnSortOrderTbl[] = {
242 REQUIRES( type >= CRYPT_CERTINFO_FIRST_DN && \
243 type <= CRYPT_CERTINFO_LAST_DN );
245 status = mapValue( type, &value, dnSortOrderTbl,
272 if( dnComponent->
type < 1 || \
273 ( dnComponent->
type > 50 && \
274 dnComponent->
type < CRYPT_CERTINFO_FIRST_DN ) ||
275 dnComponent->
type > CRYPT_CERTINFO_LAST_DN )
312 int matchCount = 0, iterationCount;
315 assert( ( value == NULL && valueLength == 0 ) || \
319 REQUIRES_N( type >= CRYPT_CERTINFO_FIRST_DN && \
320 type <= CRYPT_CERTINFO_LAST_DN );
322 REQUIRES_N( ( value == NULL && valueLength == 0 ) || \
325 REQUIRES_N( ( value == NULL && count >= 0 ) || \
326 ( value != NULL && count == 0 ) );
329 for( listPtr = dnComponentList, iterationCount = 0;
331 listPtr = listPtr->
next, iterationCount++ )
334 if( listPtr->
type != type )
344 if( matchCount++ < count )
351 !memcmp( listPtr->value, value, valueLength ) )
354 ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_MED );
374 for( listPtr = dnComponentList, iterationCount = 0;
376 listPtr = listPtr->
next, iterationCount++ )
381 !memcmp( dnComponentInfo->
oid, oid, oidLength ) )
384 ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_MED );
396 REQUIRES_N( ( type >= CRYPT_CERTINFO_FIRST_DN && \
397 type <= CRYPT_CERTINFO_LAST_DN ) || \
398 ( type > 0 && type < 50 ) );
401 for( i = 0; certInfoOIDs[ i ].oid != NULL && \
405 if( certInfoOIDs[ i ].type == type )
406 return( &certInfoOIDs[ i ] );
423 for( i = 0; certInfoOIDs[ i ].oid != NULL && \
433 if( certInfoOID->
oid[ 4 ] == oid[ 4 ] && \
434 !memcmp( certInfoOID->
oid, oid, oidLength ) )
435 return( certInfoOID );
442 #ifdef USE_CERT_DNSTRING
450 assert(
isReadPtr( label, labelLength ) );
454 for( i = 0; certInfoOIDs[ i ].oid != NULL && \
460 if( certInfoOID->
nameLen == labelLength && \
461 !
strCompare( certInfoOID->name, label, labelLength ) )
462 return( certInfoOID );
463 if( certInfoOID->altName != NULL && \
465 !
strCompare( certInfoOID->altName, label, labelLength ) )
466 return( certInfoOID );
479 const BOOLEAN fromExternalSource,
485 int newValueSortOrder, iterationCount;
487 assert( listHeadPtr == NULL || \
492 REQUIRES( ( type >= CRYPT_CERTINFO_FIRST_DN && \
493 type <= CRYPT_CERTINFO_LAST_DN ) || \
494 ( type > 0 && type < 50 ) );
497 *insertPointPtrPtr = NULL;
501 if( fromExternalSource )
503 for( insertPoint = listHeadPtr, iterationCount = 0;
504 insertPoint->
next != NULL && \
506 insertPoint = insertPoint->
next, iterationCount++ );
507 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
514 newValueSortOrder = dnSortOrder( type );
516 return( newValueSortOrder );
519 for( insertPoint = listHeadPtr, iterationCount = 0;
520 insertPoint != NULL && \
521 newValueSortOrder >= dnSortOrder( insertPoint->
type ) && \
523 insertPoint = insertPoint->
next, iterationCount++ )
530 if( insertPoint->
type == type )
532 if( errorType != NULL )
537 prevElement = insertPoint;
539 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
560 IN_BUFFER( valueLength )
const void *value,
562 IN_RANGE( 1, 20 )
const int valueStringType,
570 BYTE countryCode[ 2 + 8 ];
573 assert( listHeadPtr == NULL || \
575 assert(
isReadPtr( value, valueLength ) );
578 REQUIRES( listHeadPtr == NULL || isDNComponentValid( listHeadPtr ) );
579 REQUIRES( ( type >= CRYPT_CERTINFO_FIRST_DN && \
580 type <= CRYPT_CERTINFO_LAST_DN ) || \
581 ( type > 0 && type < 50 ) );
583 REQUIRES( valueStringType >= 1 && valueStringType <= 20 );
592 dnComponentInfo = findDNInfo( type );
593 ENSURES( dnComponentInfo != NULL );
604 ( dnComponentInfo->
wcsOK ) ? \
608 if( valueLength > ( ( flags & DN_FLAG_NOCHECK ) ? \
612 if( errorType != NULL )
618 if( listHeadPtr != NULL )
622 status = findDNInsertPoint( listHeadPtr, type,
623 ( flags & DN_FLAG_NOCHECK ) ? \
625 &insertPoint, errorType );
641 if( valueLength != 2 )
649 if( flags & DN_FLAG_NOCHECK )
654 if( !memcmp( countryCode,
"UK", 2 ) )
655 memcpy( countryCode,
"GB", 2 );
660 if( !checkCountryCode( countryCode ) )
662 if( errorType != NULL )
676 valueLength ) ) == NULL )
680 newElement->
typeInfo = dnComponentInfo;
681 memcpy( newElement->value, value, valueLength );
684 newElement->
flags = flags;
688 insertPoint, newElement );
696 IN_BUFFER( valueLength )
const void *value,
705 assert(
isReadPtr( value, valueLength ) );
708 REQUIRES( componentType >= CRYPT_CERTINFO_FIRST_DN && \
709 componentType <= CRYPT_CERTINFO_LAST_DN );
716 status = getAsn1StringInfo( value, valueLength, &valueStringType,
724 return( insertDNstring( (
DN_COMPONENT ** ) dnComponentListPtrPtr,
725 componentType, value, valueLength,
726 valueStringType, 0, errorType ) );
749 clFree(
"deleteComponent", theElement );
764 assert( listHeadPtr == NULL || \
766 assert( ( value == NULL && valueLength == 0 ) ||
770 REQUIRES( listHeadPtr == NULL || isDNComponentValid( listHeadPtr ) );
772 REQUIRES( ( value == NULL && valueLength == 0 ) || \
777 if( listHeadPtr == NULL )
786 itemToDelete = findDNComponent( listHeadPtr, type, 0,
787 value, valueLength );
788 if( itemToDelete == NULL )
790 return( deleteComponent( (
DN_COMPONENT ** ) dnComponentListPtrPtr,
797 void deleteDN(
DN_PTR **dnComponentListPtrPtr )
805 for( listPtr = *dnComponentListPtrPtr, iterationCount = 0;
819 listPtr = listPtr->
next;
820 #if defined( __GNUC__ ) && ( __GNUC__ == 4 ) && 0
826 clFree(
"deleteComponent", itemToFree );
828 ( void ) deleteComponent( &itemToFree, itemToFree );
831 ENSURES_V( iterationCount < FAILSAFE_ITERATIONS_MED );
834 *dnComponentListPtrPtr = NULL;
846 int getDNComponentInfo(
INOUT const DN_PTR *dnComponentList,
856 REQUIRES( isDNComponentValid( dnComponent ) );
860 *dnContinues =
FALSE;
866 if( dnComponent->
type >= CRYPT_CERTINFO_FIRST_DN && \
867 dnComponent->
type <= CRYPT_CERTINFO_LAST_DN )
868 *type = dnComponent->
type;
869 if( dnComponent->
next != NULL )
880 int getDNComponentValue(
const DN_PTR *dnComponentList,
884 *valueLength )
void *value,
891 assert( ( value == NULL && valueMaxLength == 0 ) || \
893 assert(
isWritePtr( valueLength,
sizeof(
int ) ) );
895 REQUIRES( isDNComponentValid( dnComponentList ) );
896 REQUIRES( type >= CRYPT_CERTINFO_FIRST_DN && \
897 type <= CRYPT_CERTINFO_LAST_DN );
898 REQUIRES( count >= 0 && count <= 100 );
899 REQUIRES( ( value == NULL && valueMaxLength == 0 ) || \
901 valueMaxLength >= 0 && \
907 memset( value, 0,
min( 16, valueMaxLength ) );
909 dnComponent = findDNComponent( dnComponentList, type, count, NULL, 0 );
910 if( dnComponent == NULL )
912 return( attributeCopyParams( value, valueMaxLength, valueLength,
932 assert( dnComponentList1 == NULL || \
934 assert( dnComponentList2 == NULL || \
936 assert( mismatchPointPtrPtr == NULL || \
940 mismatchPointPtrPtr != NULL ) );
942 isDNComponentValid( dnComponentList1 ) );
944 isDNComponentValid( dnComponentList2 ) );
947 if( mismatchPointPtrPtr )
948 *mismatchPointPtrPtr = NULL;
954 dn1ptr != NULL && dn2ptr != NULL && \
956 dn1ptr = dn1ptr->
next, dn2ptr = dn2ptr->
next, \
962 if( mismatchPointPtrPtr != NULL )
963 *mismatchPointPtrPtr = dn1ptr;
976 memcmp( dn1ptr->value, dn2ptr->value, dn1ptr->
valueLength ) ||
980 if( mismatchPointPtrPtr != NULL )
981 *mismatchPointPtrPtr = dn1ptr;
985 ENSURES_B( iterationCount < FAILSAFE_ITERATIONS_MED );
991 if( dn1ptr == NULL && dn2ptr == NULL )
993 if( dn1substring && dn1ptr == NULL )
997 if( mismatchPointPtrPtr != NULL )
998 *mismatchPointPtrPtr = dn1ptr;
1015 REQUIRES( dnSrc == NULL || isDNComponentValid( dnSrc ) );
1021 for( srcPtr = dnSrc, iterationCount= 0;
1023 srcPtr = srcPtr->
next, iterationCount++ )
1039 newElement->
prev = newElement->
next = NULL;
1043 destPtr = newElement;
1045 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
1065 IN_FLAGS( CHECKDN )
const int checkFlags,
1075 assert( dnComponentList == NULL || \
1082 REQUIRES( dnComponentList == NULL || \
1083 isDNComponentValid( dnComponentList ) );
1086 if( dnComponentList == NULL )
1090 for( dnComponentListPtr = (
DN_COMPONENT * ) dnComponentList, \
1092 dnComponentListPtr != NULL && \
1094 dnComponentListPtr = dnComponentListPtr->
next, \
1099 if( !checkCountryCode( dnComponentListPtr->value ) )
1121 seenCommonName =
TRUE;
1127 if( ( checkFlags & CHECKDN_FLAG_WELLFORMED ) && \
1134 *errorLocus = dnComponentListPtr->
type;
1139 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
1167 assert( *dnComponentListPtrPtr == NULL || \
1175 if( *dnComponentListPtrPtr == NULL )
1180 emailComponent = findDNComponentByOID( *dnComponentListPtrPtr,
1181 MKOID(
"\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" ), 11 );
1182 if( emailComponent == NULL )
1184 emailComponent = findDNComponentByOID( *dnComponentListPtrPtr,
1185 MKOID(
"\x06\x09\x09\x92\x26\x89\x93\xF2\x2C\x01\x03" ), 11 );
1187 if( emailComponent == NULL )
1200 certDataPtr = certInfoPtr->certificate;
1201 certInfoPtr->certificate = NULL;
1207 status = addCertComponentString( certInfoPtr,
1209 emailComponent->value,
1238 certInfoPtr->certificate = certDataPtr;