📄 certcset.c
字号:
if( cryptStatusError( status ) )
return( status );
isCommonNameDN = sizeofDN( certInfoPtr->subjectName ) == \
sizeofDN( tempDN );
deleteDN( &tempDN );
/* If the request DN consists only of a CN, append it to the PKI
user DN */
if( isCommonNameDN )
{
STREAM stream;
void *tempDNdata;
int tempDNsize;
/* Copy the DN template, append the user-supplied CN, and
allocate room for the encoded form */
status = copyDN( &tempDN, pkiUserInfoPtr->subjectName );
if( cryptStatusError( status ) )
return( status );
status = insertDNComponent( &tempDN, CRYPT_CERTINFO_COMMONNAME,
commonName, commonNameLength,
&certInfoPtr->errorType );
if( cryptStatusOK( status ) )
{
tempDNsize = sizeofDN( tempDN );
if( ( tempDNdata = clAlloc( "copyPkiUserInfo",
tempDNsize ) ) == NULL )
status = CRYPT_ERROR_MEMORY;
}
if( cryptStatusError( status ) )
{
if( tempDN != NULL )
deleteDN( &tempDN );
return( status );
}
/* Everything went OK, replace the existing DN with the new one
and set up the encoded form */
deleteDN( &certInfoPtr->subjectName );
certInfoPtr->subjectName = tempDN;
sMemOpen( &stream, tempDNdata, tempDNsize );
writeDN( &stream, tempDN, DEFAULT_TAG );
assert( sStatusOK( &stream ) );
sMemDisconnect( &stream );
certInfoPtr->subjectDNdata = \
certInfoPtr->subjectDNptr = tempDNdata;
certInfoPtr->subjectDNsize = tempDNsize;
return( CRYPT_OK );
}
}
/* There are full DNs present in both objects, make sure that they're
the same */
return( compareDN( certInfoPtr->subjectName,
pkiUserInfoPtr->subjectName, FALSE ) ? \
CRYPT_OK : CRYPT_ERROR_INVALID );
}
/****************************************************************************
* *
* Set Cert Info *
* *
****************************************************************************/
/* Set XYZZY certificate info */
static int setXyzzyInfo( CERT_INFO *certInfoPtr )
{
ATTRIBUTE_LIST *attributeListPtr;
const int keyUsage = CRYPT_KEYUSAGE_DIGITALSIGNATURE | \
CRYPT_KEYUSAGE_NONREPUDIATION | \
CRYPT_KEYUSAGE_KEYENCIPHERMENT | \
CRYPT_KEYUSAGE_KEYCERTSIGN | \
CRYPT_KEYUSAGE_CRLSIGN;
const time_t currentTime = getApproxTime();
int status;
/* Make sure that we haven't already set up this certificate as a XYZZY
cert */
attributeListPtr = findAttributeField( certInfoPtr->attributes,
CRYPT_CERTINFO_CERTPOLICYID,
CRYPT_ATTRIBUTE_NONE );
if( attributeListPtr != NULL && \
attributeListPtr->valueLength == sizeofOID( OID_CRYPTLIB_XYZZYCERT ) && \
!memcmp( attributeListPtr->value, OID_CRYPTLIB_XYZZYCERT,
attributeListPtr->valueLength ) )
{
setErrorInfo( certInfoPtr, CRYPT_CERTINFO_XYZZY,
CRYPT_ERRTYPE_ATTR_PRESENT );
return( CRYPT_ERROR_INITED );
}
/* Clear any existing attribute values before trying to set new ones */
certInfoPtr->startTime = certInfoPtr->endTime = 0;
deleteCertComponent( certInfoPtr, CRYPT_CERTINFO_KEYUSAGE );
deleteCertComponent( certInfoPtr, CRYPT_CERTINFO_CERTIFICATEPOLICIES );
/* Give the cert a 20-year expiry time, make it a self-signed CA cert
with all key usage types enabled, and set the policy OID to identify
it as a XYZZY cert */
certInfoPtr->startTime = currentTime;
certInfoPtr->endTime = certInfoPtr->startTime + ( 86400 * 365 * 20 );
certInfoPtr->flags |= CERT_FLAG_SELFSIGNED;
status = addCertComponent( certInfoPtr, CRYPT_CERTINFO_CA,
MESSAGE_VALUE_TRUE, CRYPT_UNUSED );
if( cryptStatusOK( status ) )
status = addCertComponent( certInfoPtr, CRYPT_CERTINFO_KEYUSAGE,
&keyUsage, CRYPT_UNUSED );
if( cryptStatusOK( status ) )
status = addCertComponent( certInfoPtr, CRYPT_CERTINFO_CERTPOLICYID,
OID_CRYPTLIB_XYZZYCERT,
sizeofOID( OID_CRYPTLIB_XYZZYCERT ) );
if( cryptStatusOK( status ) )
findAttributeFieldEx( certInfoPtr->attributes,
CRYPT_CERTINFO_CERTPOLICYID )->flags |= ATTR_FLAG_LOCKED;
return( status );
}
/* Set certificate cursor info */
static int setCertCursorInfo( CERT_INFO *certInfoPtr, const int value )
{
const BOOLEAN isCertChain = \
( certInfoPtr->type == CRYPT_CERTTYPE_CERTCHAIN ) ? \
TRUE : FALSE;
const BOOLEAN isRTCS = \
( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_REQUEST || \
certInfoPtr->type == CRYPT_CERTTYPE_RTCS_RESPONSE ) ? \
TRUE : FALSE;
assert( isCertChain || certInfoPtr->type == CRYPT_CERTTYPE_CERTIFICATE || \
certInfoPtr->type == CRYPT_CERTTYPE_CRL || isRTCS || \
certInfoPtr->type == CRYPT_CERTTYPE_OCSP_REQUEST || \
certInfoPtr->type == CRYPT_CERTTYPE_OCSP_RESPONSE );
/* If it's a single cert, there's nothing to do (see the
CRYPT_CERTINFO_CURRENT_CERTIFICATE ACL comment for why we (apparently)
allow cursor movement movement on single certificates) */
if( certInfoPtr->type == CRYPT_CERTTYPE_CERTIFICATE && \
certInfoPtr->certChainEnd <= 0 )
return( ( value == CRYPT_CURSOR_FIRST || \
value == CRYPT_CURSOR_LAST ) ? \
CRYPT_OK : CRYPT_ERROR_NOTFOUND );
switch( value )
{
case CRYPT_CURSOR_FIRST:
if( isCertChain )
certInfoPtr->certChainPos = CRYPT_ERROR;
else
if( isRTCS )
{
certInfoPtr->currentValidity = certInfoPtr->validityInfo;
if( certInfoPtr->currentValidity == NULL )
return( CRYPT_ERROR_NOTFOUND );
}
else
{
certInfoPtr->currentRevocation = certInfoPtr->revocations;
if( certInfoPtr->currentRevocation == NULL )
return( CRYPT_ERROR_NOTFOUND );
}
break;
case CRYPT_CURSOR_PREVIOUS:
if( isCertChain )
{
if( certInfoPtr->certChainPos < 0 )
return( CRYPT_ERROR_NOTFOUND );
certInfoPtr->certChainPos--;
}
else
if( isRTCS )
{
VALIDITY_INFO *valInfo = certInfoPtr->validityInfo;
if( valInfo == NULL || \
certInfoPtr->currentValidity == NULL || \
valInfo == certInfoPtr->currentValidity )
/* No validity info or we're already at the start of
the list */
return( CRYPT_ERROR_NOTFOUND );
/* Find the previous element in the list */
while( valInfo != NULL && \
valInfo->next != certInfoPtr->currentValidity )
valInfo = valInfo->next;
certInfoPtr->currentValidity = valInfo;
}
else
{
REVOCATION_INFO *revInfo = certInfoPtr->revocations;
if( revInfo == NULL || \
certInfoPtr->currentRevocation == NULL || \
revInfo == certInfoPtr->currentRevocation )
/* No revocations or we're already at the start of
the list */
return( CRYPT_ERROR_NOTFOUND );
/* Find the previous element in the list */
while( revInfo != NULL && \
revInfo->next != certInfoPtr->currentRevocation )
revInfo = revInfo->next;
certInfoPtr->currentRevocation = revInfo;
}
break;
case CRYPT_CURSOR_NEXT:
if( isCertChain )
{
if( certInfoPtr->certChainPos >= certInfoPtr->certChainEnd - 1 )
return( CRYPT_ERROR_NOTFOUND );
certInfoPtr->certChainPos++;
}
else
if( isRTCS )
{
if( certInfoPtr->currentValidity == NULL || \
certInfoPtr->currentValidity->next == NULL )
return( CRYPT_ERROR_NOTFOUND );
certInfoPtr->currentValidity = certInfoPtr->currentValidity->next;
}
else
{
if( certInfoPtr->currentRevocation == NULL || \
certInfoPtr->currentRevocation->next == NULL )
return( CRYPT_ERROR_NOTFOUND );
certInfoPtr->currentRevocation = certInfoPtr->currentRevocation->next;
}
break;
case CRYPT_CURSOR_LAST:
if( isCertChain )
certInfoPtr->certChainPos = certInfoPtr->certChainEnd - 1;
else
if( isRTCS )
{
VALIDITY_INFO *valInfo = certInfoPtr->validityInfo;
if( valInfo == NULL )
/* No validity info present */
return( CRYPT_ERROR_NOTFOUND );
/* Go to the end of the list */
while( valInfo->next != NULL )
valInfo = valInfo->next;
certInfoPtr->currentValidity = valInfo;
}
else
{
REVOCATION_INFO *revInfo = certInfoPtr->revocations;
if( revInfo == NULL )
/* No revocations present */
return( CRYPT_ERROR_NOTFOUND );
/* Go to the end of the list */
while( revInfo->next != NULL )
revInfo = revInfo->next;
certInfoPtr->currentRevocation = revInfo;
}
break;
default:
return( CRYPT_ARGERROR_NUM1 );
}
return( CRYPT_OK );
}
/* Set attribute cursor info */
static int setCursorInfo( CERT_INFO *certInfoPtr,
const CRYPT_ATTRIBUTE_TYPE certInfoType,
const int value )
{
int status;
assert( certInfoType == CRYPT_CERTINFO_CURRENT_EXTENSION || \
certInfoType == CRYPT_CERTINFO_CURRENT_FIELD || \
certInfoType == CRYPT_CERTINFO_CURRENT_COMPONENT );
/* If the new position is specified relative to a previous position, try
and move to that position. Note that the seemingly illogical
comparison is used because the cursor positioning codes are negative
values */
if( value <= CRYPT_CURSOR_FIRST && value >= CRYPT_CURSOR_LAST )
{
/* If we're moving to an extension field and there's a saved
GeneralName selection present, we've tried to select a non-present
GeneralName, so we can't move to a field in it */
if( certInfoType != CRYPT_CERTINFO_CURRENT_EXTENSION && \
certInfoPtr->currentSelection.generalName != CRYPT_ATTRIBUTE_NONE )
return( CRYPT_ERROR_NOTFOUND );
/* If it's an absolute positioning code, pre-set the attribute
cursor if required */
if( value == CRYPT_CURSOR_FIRST || value == CRYPT_CURSOR_LAST )
{
if( certInfoPtr->attributes == NULL )
return( CRYPT_ERROR_NOTFOUND );
/* It's an absolute attribute positioning code, reset the
attribute cursor to the start of the list before we try to
move it */
if( certInfoType == CRYPT_CERTINFO_CURRENT_EXTENSION )
certInfoPtr->attributeCursor = certInfoPtr->attributes;
else
/* It's a field or component positioning code, initialise the
attribute cursor if necessary */
if( certInfoPtr->attributeCursor == NULL )
certInfoPtr->attributeCursor = certInfoPtr->attributes;
}
else
/* It's a relative positioning code, return a not-inited error
rather than a not-found error if the cursor isn't set since
there may be attributes present but the cursor hasn't been
initialised yet by selecting the first or last absolute
attribute */
if( certInfoPtr->attributeCursor == NULL )
return( CRYPT_ERROR_NOTINITED );
/* Move the attribute cursor */
if( certInfoPtr->attributeCursor == NULL )
return( ( value == CRYPT_CURSOR_FIRST || \
value == CRYPT_CURSOR_LAST ) ? \
CRYPT_ERROR_NOTFOUND : CRYPT_ERROR_NOTINITED );
status = moveAttributeCursor( &certInfoPtr->attributeCursor,
certInfoType, value );
if( cryptStatusError( status ) )
return( status );
syncSelection( certInfoPtr );
return( CRYPT_OK );
}
/* It's a field in an extension, try and move to the start of the
extension that contains this field */
if( certInfoType == CRYPT_CERTINFO_CURRENT_EXTENSION )
{
ATTRIBUTE_LIST *attributeListPtr;
attributeListPtr = findAttribute( certInfoPtr->attributes, value,
TRUE );
if( attributeListPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
certInfoPtr->attributeCursor = attributeListPtr;
syncSelection( certInfoPtr );
return( CRYPT_OK );
}
assert( certInfoType == CRYPT_CERTINFO_CURRENT_FIELD || \
certInfoType == CRYPT_CERTINFO_CURRENT_COMPONENT );
assert( value >= CRYPT_CERTINFO_FIRST_EXTENSION && \
value <= CRYPT_CERTINFO_LAST_EXTENSION );
/* If it's a GeneralName selection component, locate the attribute field
that it corresponds to */
if( isGeneralNameSelectionComponent( value ) )
return( selectGeneralName( certInfoPtr, value, MAY_BE_ABSENT ) );
/* It's a standard attribute field, try and locate it */
return( moveCursorToField( certInfoPtr, value ) );
}
/****************************************************************************
* *
* Add a Component *
* *
****************************************************************************/
/* Add a certificate component */
int addCertComponent( CERT_INFO *certInfoPtr,
const CRYPT_ATTRIBUTE_TYPE certInfoType,
const void *certInfo, const int certInfoLength )
{
CRYPT_CERTIFICATE addedCert;
CERT_INFO *addedCertInfoPtr;
int status;
/* If we're adding data to a certificate, clear the error information */
if( !isPseudoInformation( certInfoType ) )
clearErrorInfo( certInfoPtr );
/* If it's a GeneralName or DN component, add it. These are special-
case attribute values, so they have to come before the attribute-
handling code */
if( isGeneralNameSelectionComponent( certInfoType ) )
{
status = selectGeneralName( certInfoPtr, certInfoType,
MAY_BE_ABSENT );
if( cryptStatusError( status ) )
return( status );
return( selectGeneralName( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
MUST_BE_PRESENT ) );
}
if( isGeneralNameComponent( certInfoType ) )
{
status = selectGeneralName( certInfoPtr, CRYPT_ATTRIBUTE_NONE,
CREATE_IF_ABSENT );
if( cryptStatusOK( status ) )
status = addAttributeField( &certInfoPtr->attributes,
( certInfoPtr->attributeCursor != NULL ) ? \
certInfoPtr->attributeCursor->fieldID : \
certInfoPtr->currentSelection.generalName,
certInfoType, certInfo, certInfoLength, ATTR_FLAG_NONE,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -