📄 comp_set.c
字号:
return( status );
return( CRYPT_OK );
}
/****************************************************************************
* *
* Copy Certificate Template Info *
* *
****************************************************************************/
/* Copy the public key, DN, and any attributes that need to be copied across.
We copy the full DN rather than just the encoded form in case the user
wants to query the request details after creating it */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int copyToCRMFRequest( INOUT CERT_INFO *crmfRequestInfoPtr,
INOUT CERT_INFO *certInfoPtr,
const CRYPT_HANDLE iCryptHandle )
{
int status;
assert( isWritePtr( crmfRequestInfoPtr, sizeof( CERT_INFO ) ) );
assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
status = copyDN( &crmfRequestInfoPtr->subjectName,
certInfoPtr->subjectName );
if( cryptStatusError( status ) )
return( status );
if( crmfRequestInfoPtr->iPubkeyContext == CRYPT_ERROR && \
crmfRequestInfoPtr->publicKeyInfo == NULL )
{
/* Only copy the key across if a key hasn't already been added
earlier as CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO. Checking for
this special case (rather than returning an error) allows the DN
information from an existing certificate to be copied into a
request for a new key */
status = copyPublicKeyInfo( crmfRequestInfoPtr, iCryptHandle, NULL );
}
if( cryptStatusOK( status ) )
{
/* We copy the attributes across after the DN because that copy is
the hardest to undo: If there are already attributes present, the
copied attributes will be mixed in among them so it's not really
possible to undo the copy later without performing a complex
selective delete */
status = copyCRMFRequestAttributes( &crmfRequestInfoPtr->attributes,
certInfoPtr->attributes );
}
if( cryptStatusError( status ) )
deleteDN( &crmfRequestInfoPtr->subjectName );
return( status );
}
/* Copy across the issuer and subject DN and serial number */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int copyToCRMFRevRequest( INOUT CERT_INFO *crmfRevRequestInfoPtr,
INOUT CERT_INFO *certInfoPtr )
{
int status;
assert( isWritePtr( crmfRevRequestInfoPtr, sizeof( CERT_INFO ) ) );
assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
/* If the info is already present then we can't add it again */
if( crmfRevRequestInfoPtr->issuerName != NULL )
{
setErrorInfo( crmfRevRequestInfoPtr, CRYPT_CERTINFO_CERTIFICATE,
CRYPT_ERRTYPE_ATTR_PRESENT );
return( CRYPT_ERROR_INITED );
}
/* Copy across the issuer name and allocate the storage that we need to
copy the subject name. We don't care about any internal structure of
the DNs so we just copy the pre-encoded form, we could in theory copy
the full DN but it isn't really the issuer (creator) of the object so
it's better if it appears to have no issuer DN than a misleading one */
status = copyIssuerDnData( crmfRevRequestInfoPtr, certInfoPtr );
if( cryptStatusError( status ) )
return( status );
status = setSerialNumber( crmfRevRequestInfoPtr,
certInfoPtr->cCertCert->serialNumber,
certInfoPtr->cCertCert->serialNumberLength );
if( cryptStatusOK( status ) && \
( crmfRevRequestInfoPtr->subjectDNdata = \
clAlloc( "copyToCRMFRevRequest",
certInfoPtr->subjectDNsize ) ) == NULL )
status = CRYPT_ERROR_MEMORY;
if( cryptStatusError( status ) )
{
clFree( "copyToCRMFRevRequest",
crmfRevRequestInfoPtr->issuerDNdata );
crmfRevRequestInfoPtr->issuerDNptr = \
crmfRevRequestInfoPtr->issuerDNdata = NULL;
crmfRevRequestInfoPtr->issuerDNsize = 0;
if( crmfRevRequestInfoPtr->cCertCert->serialNumber != NULL && \
crmfRevRequestInfoPtr->cCertCert->serialNumber != \
crmfRevRequestInfoPtr->cCertCert->serialNumberBuffer )
{
clFree( "copyToCRMFRevRequest",
crmfRevRequestInfoPtr->cCertCert->serialNumber );
}
crmfRevRequestInfoPtr->cCertCert->serialNumber = NULL;
return( status );
}
/* Copy the subject DN for use in CMP */
memcpy( crmfRevRequestInfoPtr->subjectDNdata, certInfoPtr->subjectDNptr,
certInfoPtr->subjectDNsize );
crmfRevRequestInfoPtr->subjectDNptr = crmfRevRequestInfoPtr->subjectDNdata;
crmfRevRequestInfoPtr->subjectDNsize = certInfoPtr->subjectDNsize;
return( CRYPT_OK );
}
/* Copy the certificate information to the revocation list. First we make
sure that the CA certificate hash (needed for the weird certificate ID)
is present. We add the necessary information as a pre-encoded blob since
we can't do much with the ID fields */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int copyToOCSPRequest( INOUT CERT_INFO *ocspRequestInfoPtr,
INOUT CERT_INFO *certInfoPtr )
{
STREAM stream;
DYNBUF essCertDB;
BYTE idBuffer[ 256 + 8 ], *idBufPtr = idBuffer;
const int idLength = ( int ) sizeofObject( \
sizeofAlgoID( CRYPT_ALGO_SHA1 ) + \
sizeofObject( 20 ) + sizeofObject( 20 ) + \
sizeofInteger( certInfoPtr->cCertCert->serialNumber, \
certInfoPtr->cCertCert->serialNumberLength ) );
int status;
assert( isWritePtr( ocspRequestInfoPtr, sizeof( CERT_INFO ) ) );
assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
/* Make sure that there's a CA certificate hash present */
if( !ocspRequestInfoPtr->certHashSet )
{
setErrorInfo( ocspRequestInfoPtr, CRYPT_CERTINFO_CACERTIFICATE,
CRYPT_ERRTYPE_ATTR_ABSENT );
return( CRYPT_ERROR_NOTINITED );
}
/* Generate the OCSPv1 certificate ID */
if( idLength > 256 && \
( idBufPtr = clDynAlloc( "copyToOCSPRequest", \
idLength ) ) == NULL )
return( CRYPT_ERROR_MEMORY );
sMemOpen( &stream, idBufPtr, idLength );
status = writeOCSPv1ID( &stream, certInfoPtr,
ocspRequestInfoPtr->certHash, KEYID_SIZE );
sMemDisconnect( &stream );
if( cryptStatusOK( status ) )
{
status = addRevocationEntry( &ocspRequestInfoPtr->cCertRev->revocations,
&ocspRequestInfoPtr->cCertRev->currentRevocation,
CRYPT_KEYID_NONE, idBufPtr,
idLength, FALSE );
}
if( idBufPtr != idBuffer )
clFree( "copyToOCSPRequest", idBufPtr );
if( status == CRYPT_ERROR_DUPLICATE )
{
/* If this certificate is already present in the list, set the
extended error code for it */
setErrorInfo( ocspRequestInfoPtr, CRYPT_CERTINFO_CERTIFICATE,
CRYPT_ERRTYPE_ATTR_PRESENT );
}
if( cryptStatusError( status ) )
return( status );
/* Add the certificate information again as an ESSCertID extension to
work around the problems inherent in OCSPv1 IDs */
status = dynCreate( &essCertDB, certInfoPtr->objectHandle,
CRYPT_IATTRIBUTE_ESSCERTID );
if( cryptStatusOK( status ) )
{
CRYPT_ATTRIBUTE_TYPE dummy1;
CRYPT_ERRTYPE_TYPE dummy2;
/* Since this isn't a critical extension (the ESSCertID is just a
backup for the main, albeit not very useful, ID) we continue if
there's a problem adding it */
( void ) addAttributeField( \
&ocspRequestInfoPtr->cCertRev->currentRevocation->attributes,
CRYPT_CERTINFO_CMS_SIGNINGCERT_ESSCERTID, CRYPT_ATTRIBUTE_NONE,
dynData( essCertDB ), dynLength( essCertDB ), ATTR_FLAG_NONE,
&dummy1, &dummy2 );
dynDestroy( &essCertDB );
}
return( CRYPT_OK );
}
/* Copy the certificate hash. We read the value indirectly since it's
computed on demand and may not have been evaluated yet */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int copyToRTCSRequest( INOUT CERT_INFO *rtcsRequestInfoPtr,
INOUT CERT_INFO *certInfoPtr )
{
BYTE certHash[ CRYPT_MAX_HASHSIZE + 8 ];
int certHashLength, status;
assert( isWritePtr( rtcsRequestInfoPtr, sizeof( CERT_INFO ) ) );
assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
status = getCertComponent( certInfoPtr,
CRYPT_CERTINFO_FINGERPRINT_SHA, certHash,
CRYPT_MAX_HASHSIZE, &certHashLength );
if( cryptStatusOK( status ) )
{
status = addValidityEntry( &rtcsRequestInfoPtr->cCertVal->validityInfo,
&rtcsRequestInfoPtr->cCertVal->currentValidity,
certHash, certHashLength );
}
if( status == CRYPT_ERROR_DUPLICATE )
{
/* If this certificate is already present in the list, set the
extended error code for it */
setErrorInfo( rtcsRequestInfoPtr, CRYPT_CERTINFO_CERTIFICATE,
CRYPT_ERRTYPE_ATTR_PRESENT );
}
return( status );
}
/* Copy user certificate info into a certificate object */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int copyUserCertInfo( INOUT CERT_INFO *certInfoPtr,
INOUT CERT_INFO *userCertInfoPtr,
IN_HANDLE const CRYPT_HANDLE iCryptHandle )
{
int status;
assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
assert( isWritePtr( userCertInfoPtr, sizeof( CERT_INFO ) ) );
REQUIRES( isHandleRangeValid( iCryptHandle ) );
REQUIRES( userCertInfoPtr->type == CRYPT_CERTTYPE_CERTIFICATE || \
userCertInfoPtr->type == CRYPT_CERTTYPE_CERTCHAIN );
REQUIRES( userCertInfoPtr->certificate != NULL );
/* If it's an RTCS or OCSP request, remember the responder URL if there's
one present. We can't leave it to be read out of the certificate
because authorityInfoAccess isn't a valid attribute for RTCS/OCSP
requests */
if( ( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_REQUEST && \
certInfoPtr->cCertVal->responderUrl == NULL ) || \
( certInfoPtr->type == CRYPT_CERTTYPE_OCSP_REQUEST && \
certInfoPtr->cCertRev->responderUrl == NULL ) )
{
const CRYPT_ATTRIBUTE_TYPE aiaAttribute = \
( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_REQUEST ) ? \
CRYPT_CERTINFO_AUTHORITYINFO_RTCS : \
CRYPT_CERTINFO_AUTHORITYINFO_OCSP;
SELECTION_STATE savedState;
void *responderUrl;
int urlSize = DUMMY_INIT;
/* There's no responder URL set, check whether the user certificate
contains a responder URL in the RTCS/OCSP authorityInfoAccess
GeneralName */
saveSelectionState( savedState, userCertInfoPtr );
status = selectGeneralName( userCertInfoPtr, aiaAttribute,
MAY_BE_ABSENT );
if( cryptStatusOK( status ) )
status = selectGeneralName( userCertInfoPtr,
CRYPT_ATTRIBUTE_NONE,
MUST_BE_PRESENT );
if( cryptStatusOK( status ) )
status = getCertComponent( userCertInfoPtr,
CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER,
NULL, 0, &urlSize );
if( cryptStatusOK( status ) )
{
/* There's a responder URL present, copy it to the request */
if( ( responderUrl = \
clAlloc( "copyUserCertInfo", urlSize ) ) == NULL )
status = CRYPT_ERROR_MEMORY;
else
{
status = getCertComponent( userCertInfoPtr,
CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER,
responderUrl, urlSize, &urlSize );
}
if( cryptStatusOK( status ) )
{
if( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_REQUEST )
{
certInfoPtr->cCertVal->responderUrl = responderUrl;
certInfoPtr->cCertVal->responderUrlSize = urlSize;
}
else
{
certInfoPtr->cCertRev->responderUrl = responderUrl;
certInfoPtr->cCertRev->responderUrlSize = urlSize;
}
}
}
else
{
/* If there's no responder URL present it's not a (fatal)
error */
status = CRYPT_OK;
}
restoreSelectionState( savedState, userCertInfoPtr );
if( cryptStatusError( status ) )
return( status );
}
/* Copy the required information across to the certificate */
switch( certInfoPtr->type )
{
case CRYPT_CERTTYPE_CRL:
return( copyRevocationInfo( certInfoPtr, userCertInfoPtr ) );
case CRYPT_CERTTYPE_REQUEST_CERT:
return( copyToCRMFRequest( certInfoPtr, userCertInfoPtr,
iCryptHandle ) );
case CRYPT_CERTTYPE_REQUEST_REVOCATION:
return( copyToCRMFRevRequest( certInfoPtr, userCertInfoPtr ) );
case CRYPT_CERTTYPE_OCSP_REQUEST:
return( copyToOCSPRequest( certInfoPtr, userCertInfoPtr ) );
case CRYPT_CERTTYPE_RTCS_REQUEST:
return( copyToRTCSRequest( certInfoPtr, userCertInfoPtr ) );
}
retIntError();
}
/****************************************************************************
* *
* Copy Miscellaneous Certificate Info *
* *
****************************************************************************/
/* Get the hash of the public key (for an OCSPv1 request), possibly
overwriting a previous hash if there are multiple entries in the
request */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int copyCaCertInfo( INOUT CERT_INFO *certInfoPtr,
INOUT CERT_INFO *caCertInfoPtr )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -