📄 certraw.c
字号:
/****************************************************************************
* *
* Unsigned Cert Object Routines *
* Copyright Peter Gutmann 1996-2001 *
* *
****************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <time.h>
#if defined( INC_ALL ) || defined( INC_CHILD )
#include "asn1.h"
#include "asn1objs.h"
#include "asn1oid.h"
#include "cert.h"
#else
#include "keymgmt/asn1.h"
#include "keymgmt/asn1objs.h"
#include "keymgmt/asn1oid.h"
#include "keymgmt/cert.h"
#endif /* Compiler-specific includes */
/****************************************************************************
* *
* Read/Write OCSP Data *
* *
****************************************************************************/
/* The OCSPv1 ID doesn't contain any usable fields so we pre-encode it when
the cert is added to the OCSP request and treat it as a blob thereafter */
int sizeofOCSPv1ID( const CERT_INFO *certInfoPtr )
{
return( ( int ) sizeofObject( \
sizeofAlgoID( CRYPT_ALGO_SHA ) + \
sizeofObject( 20 ) + sizeofObject( 20 ) + \
sizeofInteger( certInfoPtr->serialNumber, \
certInfoPtr->serialNumberLength ) ) );
}
int writeOCSPv1ID( STREAM *stream, const CERT_INFO *certInfoPtr,
const void *issuerKeyHash )
{
HASHFUNCTION hashFunction;
BYTE hashBuffer[ CRYPT_MAX_HASHSIZE ];
int hashSize;
/* Get the issuerName hash */
getHashParameters( CRYPT_ALGO_SHA, &hashFunction, &hashSize );
hashFunction( NULL, hashBuffer, certInfoPtr->issuerDNptr,
certInfoPtr->issuerDNsize, HASH_ALL );
/* Write the request data */
writeSequence( stream, sizeofAlgoID( CRYPT_ALGO_SHA ) + \
sizeofObject( hashSize ) + \
sizeofObject( hashSize ) + \
sizeofInteger( certInfoPtr->serialNumber,
certInfoPtr->serialNumberLength ) );
writeAlgoID( stream, CRYPT_ALGO_SHA );
writeOctetString( stream, hashBuffer, hashSize, DEFAULT_TAG );
writeOctetString( stream, issuerKeyHash, KEYID_SIZE, DEFAULT_TAG );
return( writeInteger( stream, certInfoPtr->serialNumber,
certInfoPtr->serialNumberLength, DEFAULT_TAG ) );
}
/****************************************************************************
* *
* Read/Write CMS Data *
* *
****************************************************************************/
/* Read signed attributes */
int readCMSAttributes( STREAM *stream, CERT_INFO *attributeInfoPtr )
{
/* CMS attributes are straight attribute objects so we just pass the call
through */
return( readAttributes( stream, &attributeInfoPtr->attributes,
CRYPT_CERTTYPE_CMS_ATTRIBUTES, CRYPT_UNUSED,
&attributeInfoPtr->errorLocus,
&attributeInfoPtr->errorType ) );
}
/* Write signed attributes */
int writeCMSAttributes( STREAM *stream, CERT_INFO *attributeInfoPtr )
{
ATTRIBUTE_LIST *attributeListPtr;
int addDefaultAttributes, attributeSize, status;
krnlSendMessage( DEFAULTUSER_OBJECT_HANDLE,
RESOURCE_IMESSAGE_GETATTRIBUTE, &addDefaultAttributes,
CRYPT_OPTION_CMS_DEFAULTATTRIBUTES );
/* Make sure there's a hash and content type present */
if( findAttributeField( attributeInfoPtr->attributes,
CRYPT_CERTINFO_CMS_MESSAGEDIGEST,
CRYPT_ATTRIBUTE_NONE ) == NULL )
{
setErrorInfo( attributeInfoPtr, CRYPT_CERTINFO_CMS_MESSAGEDIGEST,
CRYPT_ERRTYPE_ATTR_ABSENT );
return( CRYPT_ERROR_INVALID );
}
attributeListPtr = findAttribute( attributeInfoPtr->attributes,
CRYPT_CERTINFO_CMS_CONTENTTYPE );
if( attributeListPtr == NULL )
{
const int value = CRYPT_CONTENT_DATA;
/* If there's no content type and we're not adding it automatically,
complain */
if( !addDefaultAttributes )
{
setErrorInfo( attributeInfoPtr, CRYPT_CERTINFO_CMS_CONTENTTYPE,
CRYPT_ERRTYPE_ATTR_ABSENT );
return( CRYPT_ERROR_INVALID );
}
/* There's no content type present, treat it as straight data (which
means this is signedData) */
status = addCertComponent( attributeInfoPtr, CRYPT_CERTINFO_CMS_CONTENTTYPE,
&value, CRYPT_UNUSED );
if( cryptStatusError( status ) )
return( status );
}
/* If there's no signing time attribute present and we're adding the
default attributes, add it now */
if( addDefaultAttributes && \
( attributeListPtr = findAttribute( attributeInfoPtr->attributes,
CRYPT_CERTINFO_CMS_SIGNINGTIME ) ) == NULL )
{
const time_t currentTime = time( NULL );
status = addCertComponent( attributeInfoPtr, CRYPT_CERTINFO_CMS_SIGNINGTIME,
¤tTime, sizeof( time_t ) );
if( cryptStatusError( status ) )
return( status );
}
/* Check that the attributes are in order and determine how big the whole
mess will be */
status = checkAttributes( ATTRIBUTE_CMS, attributeInfoPtr->attributes,
&attributeInfoPtr->errorLocus,
&attributeInfoPtr->errorType );
if( cryptStatusError( status ) )
return( status );
attributeSize = sizeofAttributes( attributeInfoPtr->attributes );
/* Write the attributes */
return( writeAttributes( stream, attributeInfoPtr->attributes,
CRYPT_CERTTYPE_CMS_ATTRIBUTES, attributeSize ) );
}
/****************************************************************************
* *
* Read/Write PKI Userinfo Data *
* *
****************************************************************************/
/* The size of the binary authenticator information before checksumming and
encoding */
#define PKIUSER_AUTHENTICATOR_SIZE 12
/* The size of the encrypted user info:
sizeofObject( 2 * sizeofObject( PKIUSER_AUTHENTICATOR_SIZE ) ) + PKCS #5
padding = 2 + ( 2 + 12 + 2 + 12 ) = 30 + 2 = 32. This works for both 64-
and 128-bit block ciphers */
#define ENCRYPTED_AUTHENTICATOR_SIZE 32
/* Read PKI user info */
int readPKIUserInfo( STREAM *stream, CERT_INFO *userInfoPtr )
{
CRYPT_CONTEXT iCryptContext;
MESSAGE_CREATEOBJECT_INFO createInfo;
QUERY_INFO queryInfo;
STREAM userInfoStream;
BYTE userInfo[ 128 ];
int userInfoSize, length, status;
/* Read the user name and encryption algorithm info and the start of the
encrypted data */
userInfoPtr->subjectDNptr = sMemBufPtr( stream );
userInfoPtr->subjectDNsize = ( int ) stell( stream );
status = readDN( stream, &userInfoPtr->subjectName );
userInfoPtr->subjectDNsize = ( int ) stell( stream ) - userInfoPtr->subjectDNsize;
if( cryptStatusOK( status ) )
status = readContextAlgoID( stream, NULL, &queryInfo, DEFAULT_TAG );
if( cryptStatusOK( status ) )
status = readOctetString( stream, userInfo, &userInfoSize, 128 );
if( cryptStatusError( status ) )
return( status );
if( userInfoSize != ENCRYPTED_AUTHENTICATOR_SIZE )
return( CRYPT_ERROR_BADDATA );
/* Clone the CA key for our own use, load the IV from the encryption
info, and use the cloned context to decrypt the user info. We need to
do this to prevent problems if multiple threads try to simultaneously
decrypt with the CA key. Since user objects aren't fully implemented
yet, we use a fixed key as the CA key for now */
setMessageCreateObjectInfo( &createInfo, queryInfo.cryptAlgo );
status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -