int readDN( INOUT STREAM *stream, OUT_PTR_COND DN_PTR **dnComponentListPtrPtr ) { DN_COMPONENT *dnComponentListPtr = NULL; int length, iterationCount, status; assert( isWritePtr( stream, sizeof( STREAM ) ) ); assert( isWritePtr( dnComponentListPtrPtr, sizeof( DN_COMPONENT * ) ) ); /* Clear return value */ *dnComponentListPtrPtr = NULL; /* Read the encoded DN into the local copy of the DN (in other words into the dnComponentListPtr, not the externally-visible dnComponentListPtrPtr) */ status = readSequenceZ( stream, &length ); if( cryptStatusError( status ) ) return( status ); if( length <= 0 ) { /* Some buggy certificates include zero-length DNs, which we skip */ return( CRYPT_OK ); } for( iterationCount = 0; length > 0 && iterationCount < FAILSAFE_ITERATIONS_MED; iterationCount++ ) { const int startPos = stell( stream ); REQUIRES( startPos > 0 && startPos < MAX_INTLENGTH_SHORT ); status = readDNComponent( stream, &dnComponentListPtr ); if( cryptStatusError( status ) ) break; length -= stell( stream ) - startPos; } if( cryptStatusError( status ) || \ length < 0 || iterationCount >= FAILSAFE_ITERATIONS_MED ) { /* Delete the local copy of the DN read so far if necessary */ if( dnComponentListPtr != NULL ) deleteDN( ( DN_PTR ** ) &dnComponentListPtr ); return( cryptStatusError( status ) ? status : CRYPT_ERROR_BADDATA ); } /* Copy the local copy of the DN back to the caller */ *dnComponentListPtrPtr = dnComponentListPtr; return( CRYPT_OK ); }
int deleteCertComponent( INOUT CERT_INFO *certInfoPtr, IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE certInfoType ) { int status; assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) ); REQUIRES( isAttribute( certInfoType ) || \ isInternalAttribute( certInfoType ) ); /* If it's a GeneralName or DN component, delete it. These are special-case attribute values so they have to come before the general attribute-handling code */ if( isGeneralNameSelectionComponent( certInfoType ) ) { /* Check whether this GeneralName is present */ status = selectGeneralName( certInfoPtr, certInfoType, MUST_BE_PRESENT ); if( cryptStatusError( status ) ) return( status ); /* Delete each field in the GeneralName */ if( deleteCompositeAttributeField( &certInfoPtr->attributes, &certInfoPtr->attributeCursor, certInfoPtr->attributeCursor, certInfoPtr->currentSelection.dnPtr ) == OK_SPECIAL ) { /* We've deleted the attribute containing the currently selected DN, deselect it */ certInfoPtr->currentSelection.dnPtr = NULL; } return( CRYPT_OK ); } if( isGeneralNameComponent( certInfoType ) ) { SELECTION_STATE selectionState; ATTRIBUTE_PTR *attributePtr = DUMMY_INIT_PTR; /* Find the requested GeneralName component. Since selectGeneralNameComponent() changes the current selection within the GeneralName, we save the selection state around the call */ saveSelectionState( selectionState, certInfoPtr ); status = selectGeneralNameComponent( certInfoPtr, certInfoType ); if( cryptStatusOK( status ) ) attributePtr = certInfoPtr->attributeCursor; restoreSelectionState( selectionState, certInfoPtr ); if( cryptStatusError( status )) return( status ); ENSURES( attributePtr != NULL ); /* Delete the field within the GeneralName */ if( deleteAttributeField( &certInfoPtr->attributes, &certInfoPtr->attributeCursor, attributePtr, certInfoPtr->currentSelection.dnPtr ) == OK_SPECIAL ) { /* We've deleted the attribute containing the currently selected DN, deselect it */ certInfoPtr->currentSelection.dnPtr = NULL; } return( CRYPT_OK ); } if( isDNComponent( certInfoType ) ) { status = selectDN( certInfoPtr, CRYPT_ATTRIBUTE_NONE, MUST_BE_PRESENT ); if( cryptStatusOK( status ) ) status = deleteDNComponent( certInfoPtr->currentSelection.dnPtr, certInfoType, NULL, 0 ); return( status ); } /* If it's standard certificate or CMS attribute, delete it */ if( ( certInfoType >= CRYPT_CERTINFO_FIRST_EXTENSION && \ certInfoType <= CRYPT_CERTINFO_LAST_EXTENSION ) || \ ( certInfoType >= CRYPT_CERTINFO_FIRST_CMS && \ certInfoType <= CRYPT_CERTINFO_LAST_CMS ) ) return( deleteCertAttribute( certInfoPtr, certInfoType ) ); /* If it's anything else, handle it specially */ switch( certInfoType ) { case CRYPT_CERTINFO_SELFSIGNED: if( !( certInfoPtr->flags & CERT_FLAG_SELFSIGNED ) ) return( CRYPT_ERROR_NOTFOUND ); certInfoPtr->flags &= ~CERT_FLAG_SELFSIGNED; return( CRYPT_OK ); case CRYPT_CERTINFO_CURRENT_CERTIFICATE: case CRYPT_ATTRIBUTE_CURRENT_GROUP: case CRYPT_ATTRIBUTE_CURRENT: case CRYPT_ATTRIBUTE_CURRENT_INSTANCE: if( certInfoPtr->attributeCursor == NULL ) return( CRYPT_ERROR_NOTFOUND ); if( certInfoType == CRYPT_ATTRIBUTE_CURRENT_GROUP ) { status = deleteAttribute( &certInfoPtr->attributes, &certInfoPtr->attributeCursor, certInfoPtr->attributeCursor, certInfoPtr->currentSelection.dnPtr ); } else { /* The current component and field are essentially the same thing since a component is one of a set of entries in a multivalued field, thus they're handled identically */ status = deleteAttributeField( &certInfoPtr->attributes, &certInfoPtr->attributeCursor, certInfoPtr->attributeCursor, certInfoPtr->currentSelection.dnPtr ); } if( status == OK_SPECIAL ) { /* We've deleted the attribute containing the currently selected DN, deselect it */ certInfoPtr->currentSelection.dnPtr = NULL; } return( CRYPT_OK ); case CRYPT_CERTINFO_TRUSTED_USAGE: if( certInfoPtr->cCertCert->trustedUsage == CRYPT_ERROR ) return( CRYPT_ERROR_NOTFOUND ); certInfoPtr->cCertCert->trustedUsage = CRYPT_ERROR; return( CRYPT_OK ); case CRYPT_CERTINFO_TRUSTED_IMPLICIT: return( krnlSendMessage( certInfoPtr->ownerHandle, IMESSAGE_USER_TRUSTMGMT, &certInfoPtr->objectHandle, MESSAGE_TRUSTMGMT_DELETE ) ); case CRYPT_CERTINFO_VALIDFROM: case CRYPT_CERTINFO_THISUPDATE: if( certInfoPtr->startTime <= 0 ) return( CRYPT_ERROR_NOTFOUND ); certInfoPtr->startTime = 0; return( CRYPT_OK ); case CRYPT_CERTINFO_VALIDTO: case CRYPT_CERTINFO_NEXTUPDATE: if( certInfoPtr->endTime <= 0 ) return( CRYPT_ERROR_NOTFOUND ); certInfoPtr->endTime = 0; return( CRYPT_OK ); case CRYPT_CERTINFO_SUBJECTNAME: if( certInfoPtr->currentSelection.dnPtr == &certInfoPtr->subjectName ) { /* This is the currently selected DN, deselect it before deleting it */ certInfoPtr->currentSelection.dnPtr = NULL; } deleteDN( &certInfoPtr->subjectName ); return( CRYPT_OK ); #ifdef USE_CERTREV case CRYPT_CERTINFO_REVOCATIONDATE: { time_t *revocationTimePtr = ( time_t * ) \ getRevocationTimePtr( certInfoPtr ); if( revocationTimePtr == NULL ) return( CRYPT_ERROR_NOTFOUND ); *revocationTimePtr = 0; return( CRYPT_OK ); } #endif /* USE_CERTREV */ #ifdef USE_PKIUSER case CRYPT_CERTINFO_PKIUSER_RA: if( !certInfoPtr->cCertUser->isRA ) return( CRYPT_ERROR_NOTFOUND ); certInfoPtr->cCertUser->isRA = FALSE; return( CRYPT_OK ); #endif /* USE_PKIUSER */ } retIntError(); }