21 #define MAX_ID_SIZE 128
32 #define CRL_SORT_LIMIT 1024
62 static
int findRevocationEntry(
const REVOCATION_INFO *listPtr,
68 const REVOCATION_INFO *prevElement = NULL;
69 const int idCheck = checksumData( value, valueLength );
72 assert(
isReadPtr( listPtr,
sizeof( REVOCATION_INFO ) ) );
73 assert(
isWritePtr( insertPoint,
sizeof( REVOCATION_INFO * ) ) );
74 assert(
isReadPtr( value, valueLength ) );
89 for( iterationCount = 0;
91 listPtr = listPtr->next, iterationCount++ )
93 if( ( sortEntries || idCheck == listPtr->idCheck ) && \
94 listPtr->idLength == valueLength )
96 const int compareStatus = memcmp( listPtr->id,
103 *insertPoint = ( REVOCATION_INFO * ) listPtr;
106 if( sortEntries && compareStatus > 0 )
111 if( sortEntries && listPtr->idLength > valueLength )
115 prevElement = listPtr;
117 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
121 *insertPoint = ( REVOCATION_INFO * ) prevElement;
128 int addRevocationEntry(
INOUT_PTR REVOCATION_INFO **listHeadPtrPtr,
131 IN_BUFFER( valueLength )
const void *value,
135 REVOCATION_INFO *newElement, *insertPoint;
137 assert(
isWritePtr( listHeadPtrPtr,
sizeof( REVOCATION_INFO * ) ) );
138 assert(
isWritePtr( newEntryPosition,
sizeof( REVOCATION_INFO * ) ) );
139 assert(
isReadPtr( value, valueLength ) );
142 valueType == CRYPT_IKEYID_CERTID || \
143 valueType == CRYPT_IKEYID_ISSUERID || \
144 valueType == CRYPT_IKEYID_ISSUERANDSERIALNUMBER );
148 *newEntryPosition = NULL;
155 if( !noCheck && *listHeadPtrPtr != NULL && \
157 findRevocationEntry( *listHeadPtrPtr, &insertPoint, value,
158 valueLength,
TRUE ) ) )
171 if( ( newElement = ( REVOCATION_INFO * ) \
172 clAlloc(
"addRevocationEntry", \
173 sizeof( REVOCATION_INFO ) + valueLength ) ) == NULL )
176 newElement->id = newElement->value;
177 newElement->idType = valueType;
178 memcpy( newElement->id, value, valueLength );
180 newElement->idCheck = checksumData( value, valueLength );
184 *newEntryPosition = newElement;
192 void deleteRevocationEntries(
INOUT_PTR REVOCATION_INFO **listHeadPtrPtr )
194 REVOCATION_INFO *entryListPtr = *listHeadPtrPtr;
197 assert(
isWritePtr( listHeadPtrPtr,
sizeof( REVOCATION_INFO * ) ) );
199 *listHeadPtrPtr = NULL;
202 for( iterationCount = 0;
206 REVOCATION_INFO *itemToFree = entryListPtr;
208 entryListPtr = entryListPtr->next;
209 if( itemToFree->attributes != NULL )
210 deleteAttributes( &itemToFree->attributes );
211 zeroise( itemToFree,
sizeof( REVOCATION_INFO ) );
212 clFree(
"deleteRevocationEntries", itemToFree );
219 int prepareRevocationEntries(
INOUT_OPT REVOCATION_INFO *listPtr,
220 const time_t defaultTime,
228 REVOCATION_INFO *revocationEntry;
233 assert( listPtr == NULL || \
234 isReadPtr( listPtr,
sizeof( REVOCATION_INFO ) ) );
235 assert(
isWritePtr( errorEntry,
sizeof( REVOCATION_INFO * ) ) );
243 if( listPtr == NULL )
248 for( revocationEntry = listPtr, iterationCount = 0;
250 revocationEntry = revocationEntry->next, iterationCount++ )
253 revocationEntry->revocationTime = currentTime;
268 status = getAttributeFieldValue( revocationEntry->attributes,
273 time_t invalidityDate;
277 status = getAttributeFieldTime( revocationEntry->attributes,
285 status = addAttributeFieldString( &revocationEntry->attributes,
288 &revocationEntry->revocationTime,
290 errorLocus, errorType );
294 *errorEntry = revocationEntry;
302 revocationEntry->revocationTime = invalidityDate;
311 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
314 for( revocationEntry = listPtr, iterationCount = 0;
316 revocationEntry = revocationEntry->next, iterationCount++ )
318 if( revocationEntry->attributes != NULL )
321 revocationEntry->attributes,
322 errorLocus, errorType );
326 *errorEntry = revocationEntry;
336 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
353 CERT_REV_INFO *certRevInfo = revocationInfoPtr->cCertRev;
354 REVOCATION_INFO *revocationEntry;
362 if( certRevInfo->revocations == NULL )
366 if( ( revocationInfoPtr->issuerDNsize != certInfoPtr->
issuerDNsize || \
367 memcmp( revocationInfoPtr->issuerDNptr, certInfoPtr->issuerDNptr,
372 status = findRevocationEntry( certRevInfo->revocations, &revocationEntry,
373 certInfoPtr->cCertCert->serialNumber,
374 certInfoPtr->cCertCert->serialNumberLength,
381 ENSURES( revocationEntry != NULL );
385 certRevInfo->currentRevocation = revocationEntry;
405 (
void ** ) &crlInfoPtr,
409 if( crlInfoPtr->certificate == NULL )
418 status = checkRevocationCRL( certInfoPtr, crlInfoPtr );
434 for( i = 0; i < certInfoPtr->cCertCert->chainEnd && \
440 status = krnlAcquireObject( certInfoPtr->cCertCert->chain[ i ],
442 (
void ** ) &certChainInfoPtr,
446 status = checkRevocationCRL( certChainInfoPtr, crlInfoPtr );
454 certInfoPtr->cCertCert->chainPos = i;
458 ENSURES( i < MAX_CHAINLENGTH );
479 int sizeofCRLentry(
INOUT REVOCATION_INFO *crlEntry )
483 assert(
isWritePtr( crlEntry,
sizeof( REVOCATION_INFO ) ) );
492 return( (
int ) sizeofObject( \
495 ( ( crlEntry->attributeSize > 0 ) ? \
496 (
int ) sizeofObject( crlEntry->attributeSize ) : 0 ) ) );
501 INOUT_PTR REVOCATION_INFO **listHeadPtrPtr,
508 REVOCATION_INFO *currentEntry;
511 time_t revocationTime;
514 assert(
isWritePtr( listHeadPtrPtr,
sizeof( REVOCATION_INFO * ) ) );
521 status = readSequence( stream, &length );
524 endPos = stell( stream ) +
length;
529 &serialNumberLength );
537 status = addRevocationEntry( listHeadPtrPtr, ¤tEntry,
538 CRYPT_IKEYID_ISSUERANDSERIALNUMBER,
539 serialNumber, serialNumberLength,
543 currentEntry->revocationTime = revocationTime;
551 status = readAttributes( stream, ¤tEntry->attributes,
553 errorLocus, errorType );
563 const REVOCATION_INFO *crlEntry )
565 const int revocationLength = \
566 sizeofInteger( crlEntry->id, crlEntry->idLength ) + \
568 ( ( crlEntry->attributeSize > 0 ) ? \
569 (
int ) sizeofObject( crlEntry->attributeSize ) : 0 );
573 assert(
isReadPtr( crlEntry,
sizeof( REVOCATION_INFO ) ) );
576 writeSequence( stream, revocationLength );
577 writeInteger( stream, crlEntry->id, crlEntry->idLength,
DEFAULT_TAG );
578 status = writeUTCTime( stream, crlEntry->revocationTime,
DEFAULT_TAG );
586 return( writeAttributes( stream, crlEntry->attributes,
601 int checkRevocationOCSP(
const CERT_INFO *certInfoPtr,
604 CERT_REV_INFO *certRevInfo = revocationInfoPtr->cCertRev;
607 int certHashLength,
status;
614 if( certRevInfo->revocations == NULL )
621 status = getCertComponentString( (
CERT_INFO * ) certInfoPtr,
627 status = findRevocationEntry( certRevInfo->revocations,
628 &revocationEntry, certHash,
629 certHashLength,
FALSE );
637 ENSURES( revocationEntry != NULL );
643 certRevInfo->currentRevocation = revocationEntry;
654 int copyRevocationEntries(
INOUT_PTR REVOCATION_INFO **destListHeadPtrPtr,
657 const REVOCATION_INFO *srcListCursor;
661 assert(
isWritePtr( destListHeadPtrPtr,
sizeof( REVOCATION_INFO * ) ) );
662 assert(
isReadPtr( srcListPtr,
sizeof( REVOCATION_INFO ) ) );
666 REQUIRES( *destListHeadPtrPtr == NULL );
669 for( srcListCursor = srcListPtr, iterationCount = 0;
671 srcListCursor = srcListCursor->next, iterationCount++ )
673 REVOCATION_INFO *newElement;
678 if( ( newElement = ( REVOCATION_INFO * ) \
679 clAlloc(
"copyRevocationEntries",
680 sizeof( REVOCATION_INFO ) + \
681 srcListCursor->idLength ) ) == NULL )
684 newElement->id = newElement->value;
685 newElement->attributes = NULL;
686 newElement->next = NULL;
696 destListCursor = newElement;
698 ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
714 REVOCATION_INFO *revocationInfo;
724 for( revocationInfo = certInfoPtr->cCertRev->revocations,
726 revocationInfo != NULL && iterationCount < FAILSAFE_ITERATIONS_LARGE;
727 revocationInfo = revocationInfo->next, iterationCount++ )
732 const BYTE *
id = revocationInfo->id;
736 revocationInfo->idType == CRYPT_IKEYID_CERTID || \
737 revocationInfo->idType == CRYPT_IKEYID_ISSUERID );
752 idType = revocationInfo->altIdType;
753 id = revocationInfo->altID;
804 status = krnlAcquireObject( getkeyInfo.
cryptHandle,
806 (
void ** ) &crlEntryInfoPtr,
810 const REVOCATION_INFO *crlRevocationInfo;
812 crlRevocationInfo = crlEntryInfoPtr->cCertRev->revocations;
813 if( crlRevocationInfo != NULL )
815 revocationInfo->revocationTime = \
816 crlRevocationInfo->revocationTime;
817 if( crlRevocationInfo->attributes != NULL )
822 ( void ) copyRevocationAttributes( &revocationInfo->attributes,
823 crlRevocationInfo->attributes );
834 ENSURES( iterationCount < FAILSAFE_ITERATIONS_LARGE );
871 static
int sizeofOcspID(
const REVOCATION_INFO *ocspEntry )
873 assert(
isReadPtr( ocspEntry,
sizeof( REVOCATION_INFO ) ) );
880 return( ocspEntry->idLength );
901 getHashAtomicParameters(
CRYPT_ALGO_SHA1, 0, &hashFunctionAtomic, NULL );
905 memset(
id, 0,
min( 16, idMaxLen ) );
909 tag = peekTag( stream );
922 status = getStreamObjectLength( stream, &length );
927 if( length > idMaxLen )
930 return( sread( stream,
id, length ) );
934 *idType = CRYPT_IKEYID_CERTID;
937 status = readConstructed( stream, &length, 0 );
939 status = sMemGetDataBlock( stream, &dataPtr, length );
943 return( readUniversal( stream ) );
950 *idType = CRYPT_IKEYID_ISSUERID;
953 readSequence( stream, NULL );
954 status = getStreamObjectLength( stream, &length );
956 status = sMemGetDataBlock( stream, &dataPtr, length );
960 sSkip( stream, length );
961 readUniversal( stream );
962 return( readUniversal( stream ) );
970 const REVOCATION_INFO *ocspEntry )
973 assert(
isReadPtr( ocspEntry,
sizeof( REVOCATION_INFO ) ) );
975 return( swrite( stream, ocspEntry->id, ocspEntry->idLength ) );
986 int sizeofOcspRequestEntry(
INOUT REVOCATION_INFO *ocspEntry )
990 assert(
isWritePtr( ocspEntry,
sizeof( REVOCATION_INFO ) ) );
1002 sizeofObject( sizeofOcspID( ocspEntry ) + \
1003 ( ( ocspEntry->attributeSize > 0 ) ? \
1006 sizeofObject( ocspEntry->attributeSize ) ) : 0 ) ) );
1011 INOUT_PTR REVOCATION_INFO **listHeadPtrPtr,
1015 REVOCATION_INFO *currentEntry;
1023 assert(
isWritePtr( listHeadPtrPtr,
sizeof( REVOCATION_INFO * ) ) );
1027 status = readSequence( stream, &length );
1030 endPos = stell( stream ) +
length;
1033 status = readOcspID( stream, &idType, idBuffer,
MAX_ID_SIZE, &length );
1038 status = addRevocationEntry( listHeadPtrPtr, ¤tEntry, idType,
1039 idBuffer, length,
FALSE );
1054 status = readAttributes( stream, ¤tEntry->attributes,
1056 &certInfoPtr->errorLocus,
1057 &certInfoPtr->errorType );
1073 if( attributePtr == NULL )
1078 status = getAttributeDataPtr( attributePtr, &certIdPtr, &certIdLength );
1081 sMemConnect( &certIdStream, certIdPtr, certIdLength );
1082 readSequence( &certIdStream, NULL );
1087 currentEntry->altIdType = CRYPT_IKEYID_CERTID;
1088 memcpy( currentEntry->altID, idBuffer, length );
1090 sMemDisconnect( &certIdStream );
1097 const REVOCATION_INFO *ocspEntry )
1099 const int attributeSize = ( ocspEntry->attributeSize > 0 ) ? \
1100 (
int ) sizeofObject( \
1101 sizeofObject( ocspEntry->attributeSize ) ) : 0;
1105 assert(
isReadPtr( ocspEntry,
sizeof( REVOCATION_INFO ) ) );
1108 writeSequence( stream, sizeofOcspID( ocspEntry ) + attributeSize );
1109 status = writeOcspID( stream, ocspEntry );
1119 writeConstructed( stream, sizeofObject( ocspEntry->attributeSize ),
1121 return( writeAttributes( stream, ocspEntry->attributes,
1142 int sizeofOcspResponseEntry(
INOUT REVOCATION_INFO *ocspEntry )
1144 int certStatusSize = 0,
status;
1146 assert(
isWritePtr( ocspEntry,
sizeof( REVOCATION_INFO ) ) );
1160 sizeofObject( sizeofOcspID( ocspEntry ) + \
1162 ( ( ocspEntry->attributeSize > 0 ) ? \
1163 (
int ) sizeofObject( ocspEntry->attributeSize ) : 0 ) );
1168 INOUT_PTR REVOCATION_INFO **listHeadPtrPtr,
1171 REVOCATION_INFO *currentEntry;
1177 assert(
isWritePtr( listHeadPtrPtr,
sizeof( REVOCATION_INFO * ) ) );
1181 status = readSequence( stream, &length );
1184 endPos = stell( stream ) +
length;
1187 status = readOcspID( stream, &idType, idBuffer,
MAX_ID_SIZE, &length );
1192 status = addRevocationEntry( listHeadPtrPtr, ¤tEntry, idType,
1193 idBuffer, length,
FALSE );
1198 status = tag = peekTag( stream );
1205 status = readUniversal( stream );
1212 ¤tEntry->revocationTime );
1217 readConstructed( stream, NULL, 0 );
1224 status = readUniversal( stream );
1235 readConstructed( stream, NULL, 0 );
1251 status = readAttributes( stream, ¤tEntry->attributes,
1253 &certInfoPtr->errorLocus, &certInfoPtr->errorType );
1269 status = addAttributeField( ¤tEntry->attributes,
1272 &certInfoPtr->errorLocus,
1273 &certInfoPtr->errorType );
1281 const REVOCATION_INFO *ocspEntry,
1282 const time_t entryTime )
1284 int certStatusSize,
status;
1287 assert(
isReadPtr( ocspEntry,
sizeof( REVOCATION_INFO ) ) );
1294 writeSequence( stream, sizeofOcspID( ocspEntry ) + \
1296 ( ( ocspEntry->attributeSize > 0 ) ? \
1297 (
int ) sizeofObject( ocspEntry->attributeSize ) : 0 ) );
1298 status = writeOcspID( stream, ocspEntry );
1307 writeGeneralizedTime( stream, ocspEntry->revocationTime,
1316 writeNull( stream, ocspEntry->status );
1325 status = writeGeneralizedTime( stream, entryTime,
DEFAULT_TAG );
1333 return( writeAttributes( stream, ocspEntry->attributes,