Esempio n. 1
0
static int adjustPkiUserAttributes( INOUT CERT_INFO *certInfoPtr )
	{
	int status;

	assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );

	/* The SCEP protocol requires that the SCEP challenge password be placed 
	   in the PKCS #10 request instead of being included in the SCEP 
	   metadata.  This shouldn't have been copied across to the certificate 
	   request since the NOCOPY flag was set for the attribute, but to make 
	   absolutely certain we try and delete it anyway.  Since this could in 
	   theory be present in non-SCEP requests as well (the request-
	   processing code just knows about PKCS #10 requests as a whole, not 
	   requests from a SCEP source vs. requests not from a SCEP source), we 
	   make the delete unconditional */
	if( findAttributeField( certInfoPtr->attributes,
							CRYPT_CERTINFO_CHALLENGEPASSWORD, 
							CRYPT_ATTRIBUTE_NONE ) != NULL )
		{
		status = deleteCompleteAttribute( &certInfoPtr->attributes,
										  &certInfoPtr->attributeCursor, 
										  CRYPT_CERTINFO_CHALLENGEPASSWORD, 
										  certInfoPtr->currentSelection.dnPtr );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* The PKI user information contains an sKID that's used to uniquely 
	   identify the user, this applies to the user information itself rather 
	   than the certificate that'll be issued from it.  Since this will have 
	   been copied over alongside the other attributes we need to explicitly 
	   delete it before we continue */
	if( findAttributeField( certInfoPtr->attributes,
							CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER, 
							CRYPT_ATTRIBUTE_NONE ) != NULL )
		{
		status = deleteCompleteAttribute( &certInfoPtr->attributes,
										  &certInfoPtr->attributeCursor, 
										  CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER, 
										  certInfoPtr->currentSelection.dnPtr );
		if( cryptStatusError( status ) )
			return( status );
		}

	return( CRYPT_OK );
	}
static BOOLEAN checkEmptyDnOK( INOUT CERT_INFO *subjectCertInfoPtr )
	{
	ATTRIBUTE_PTR *attributePtr;
	int value, complianceLevel, status;

	assert( isWritePtr( subjectCertInfoPtr, sizeof( CERT_INFO ) ) );

	/* PKIX allows empty subject DNs if a subject altName is present, 
	   however creating certificates like this breaks every certificate-
	   using protocol supported by cryptlib so we only allow it at the 
	   highest compliance level */
	if( cryptStatusError( \
			krnlSendMessage( subjectCertInfoPtr->ownerHandle,
							 IMESSAGE_GETATTRIBUTE, &complianceLevel,
							 CRYPT_OPTION_CERT_COMPLIANCELEVEL ) ) || \
		complianceLevel < CRYPT_COMPLIANCELEVEL_PKIX_FULL )
		{
		/* We only allow this behaviour at the highest compliance level */
		return( FALSE );
		}
	   
	/* We also have to be very careful to ensure that the empty subject 
	   DN can't end up becoming an empty issuer DN, which can occur if it's 
	   a self-signed certificate */
	if( subjectCertInfoPtr->flags & CERT_FLAG_SELFSIGNED )
		{
		/* We can't have an empty issuer (== subject) DN */
		return( FALSE );
		}

	/* In addition if it's a CA certificate then the subject DN can't be 
	   empty, for obvious reasons */
	status = getAttributeFieldValue( subjectCertInfoPtr->attributes,
									 CRYPT_CERTINFO_CA, CRYPT_ATTRIBUTE_NONE,
									 &value );
	if( cryptStatusOK( status ) && value > 0 )
		{
		/* It's a CA certificate, the subject DN can't be empty */
		return( FALSE );
		}

	/* Finally, if there's no subject DN present then there has to be an 
	   altName present to take its place */
	attributePtr = findAttributeField( subjectCertInfoPtr->attributes,
									   CRYPT_CERTINFO_SUBJECTALTNAME,
									   CRYPT_ATTRIBUTE_NONE );
	if( attributePtr == NULL )
		{
		/* Either a subject DN or subject altName must be present */
		return( FALSE );
		}

	/* There's a subject altName present but no subject DN, mark the altName 
	   as critical */
	setAttributeProperty( attributePtr, ATTRIBUTE_PROPERTY_CRITICAL, 0 );

	return( TRUE );
	}
Esempio n. 3
0
static int moveCursorToField( INOUT CERT_INFO *certInfoPtr,
							  IN_ATTRIBUTE \
									const CRYPT_ATTRIBUTE_TYPE certInfoType )
	{
	const ATTRIBUTE_PTR *attributePtr;

	assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );

	REQUIRES( sanityCheckSelectionInfo( certInfoPtr ) );
	REQUIRES( certInfoType >= CRYPT_CERTINFO_FIRST_EXTENSION && \
			  certInfoType <= CRYPT_CERTINFO_LAST );

	/* Try and locate the given field in the extension */
	attributePtr = findAttributeField( certInfoPtr->attributes,
									   certInfoType, CRYPT_ATTRIBUTE_NONE );
	if( attributePtr == NULL )
		return( CRYPT_ERROR_NOTFOUND );

	/* We've found the given field, update the cursor and select the DN within
	   it if it's present */
	certInfoPtr->currentSelection.updateCursor = FALSE;
	certInfoPtr->attributeCursor = ( ATTRIBUTE_PTR * ) attributePtr;
	if( isGeneralNameSelectionComponent( certInfoType ) )
		{
		/* If this is a GeneralName, select the DN within it if there's one
		   present.  Since this is peripheral to the main operation of 
		   moving the cursor we ignore the return status */
		( void ) findDnInGeneralName( certInfoPtr, FALSE );

		/* We've selected the GeneralName (possibly as a side-effect of its
		   on-demand creation), clear the saved GeneralName-to-be-created
		   value */
		certInfoPtr->currentSelection.generalName = CRYPT_ATTRIBUTE_NONE;
		}

	ENSURES( sanityCheckSelectionInfo( certInfoPtr ) );

	return( CRYPT_OK );
	}