📄 certutil.c
字号:
return( ERROR_BADARG );
}
strcpy( dnBuffer, argPtr );
argPtr += strlen( argPtr );
status = parseDN( dnInfo, dnBuffer );
if( cryptStatusError( status ) )
return( status );
break;
case 'F':
keyFileName = argPtr + 1;
argPtr += strlen( argPtr );
break;
case 'K':
doKeygen = TRUE;
if( argPtr[ 1 ] )
{
if( toupper( argPtr[ 1 ] ) != 'S' )
{
puts( "Unknown key generation parameter." );
return( ERROR_BADARG );
}
optionFlag = TRUE;
argPtr++;
}
argPtr++;
break;
case 'L':
label = argPtr + 1;
argPtr += strlen( argPtr );
break;
case 'O':
doOverwriteOutput = TRUE;
argPtr++;
break;
case 'P':
password = argPtr + 1;
argPtr += strlen( argPtr );
break;
case 'S':
doSign = TRUE;
if( argPtr[ 1 ] )
{
if( toupper( argPtr[ 1 ] ) != 'C' )
{
puts( "Unknown output format parameter." );
return( ERROR_BADARG );
}
optionFlag = TRUE;
argPtr++;
}
argPtr++;
break;
case 'U':
doUpdate = TRUE;
argPtr++;
break;
case 'V':
doView = TRUE;
argPtr++;
break;
case 'X':
doExtract = TRUE;
argPtr++;
break;
default:
printf( "Unknown option '%c'.\n", *argPtr );
return( ERROR_BADARG );
}
}
argc--;
argv++;
}
/* Make sure we aren't trying to do too many things at once */
status = 0;
if( doView ) status++;
if( doExtract ) status++;
if( doKeygen ) status++;
if( doSign ) status++;
if( doUpdate ) status++;
if( !status )
{
puts( "Nothing to do, you need to specify a command option." );
return( ERROR_BADARG );
}
if( status > 1 )
{
puts( "You can't perform that many types of operation at once." );
return( ERROR_BADARG );
}
/* Generate a key */
if( doKeygen )
{
/* Make sure the file arg is in order */
if( argc <= 1 )
{
puts( "You need to specify an output file for the key to be "
"generated into." );
return( ERROR_BADARG );
}
status = checkFileExists( argv[ 1 ], doOverwriteOutput );
if( status != CRYPT_OK )
return( status );
/* Generate the key + cert request/cert */
status = generateKey( argv[ 1 ], password, label, dnInfo, optionFlag );
}
/* Extract a key from a private key file */
if( doExtract )
{
CRYPT_KEYSET cryptKeyset;
CRYPT_HANDLE cryptHandle;
FILE *outFile;
BYTE buffer[ BUFFER_SIZE ];
int size;
/* Make sure the files are right */
if( keyFileName == NULL )
{
puts( "You must specify a keyfile to export the cert object from." );
return( ERROR_BADARG );
}
if( argc <= 1 )
{
puts( "You need to specify an output file to export the cert "
"object into." );
return( ERROR_BADARG );
}
status = checkFileExists( argv[ 1 ], doOverwriteOutput );
if( status != CRYPT_OK )
return( status );
if( ( outFile = fopen( argv[ 1 ], "wb" ) ) == NULL )
{
perror( argv[ 1 ] );
return( ERROR_FILE_INPUT );
}
/* Get the public key (with attached cert info) from the private key
keyset */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
keyFileName, CRYPT_KEYOPT_READONLY );
if( cryptStatusOK( status ) )
{
status = cryptGetPublicKey( cryptKeyset, &cryptHandle,
CRYPT_KEYID_NONE, NULL );
cryptKeysetClose( cryptKeyset );
}
if( cryptStatusError( status ) )
{
fclose( outFile );
printf( "Couldn't read certificate object from private key "
"file, error code %d.\n", status );
return( -status );
}
/* Export the certificate object to the output file */
status = cryptExportCert( buffer, &size,
CRYPT_CERTFORMAT_CERTIFICATE, cryptHandle );
if( cryptStatusOK( status ) )
fwrite( buffer, 1, size, outFile );
cryptDestroyObject( cryptHandle );
if( cryptStatusError( status ) )
printf( "Couldn't extract certificate object, error code %d.\n",
status );
/* Clean up */
fclose( outFile );
}
/* Display/check a cert object */
if( doView )
{
FILE *inFile;
BYTE buffer[ BUFFER_SIZE ];
int count;
if( argc <= 1 )
{
puts( "You need to specify an input file to read the cert "
"object from." );
return( ERROR_BADARG );
}
if( ( inFile = fopen( argv[ 1 ], "rb" ) ) == NULL )
{
perror( argv[ 1 ] );
return( ERROR_FILE_INPUT );
}
/* Import the cert object from the file */
count = fread( buffer, 1, BUFFER_SIZE, inFile );
fclose( inFile );
if( count == BUFFER_SIZE ) /* Item too large for buffer */
{
printf( "Certificate object in file %s is too large for the "
"internal buffer.\n", argv[ 1 ] );
return( ERROR_FILE_INPUT );
}
status = cryptImportCert( buffer, count, CRYPT_UNUSED, &certificate );
/* Display it */
if( cryptStatusOK( status ) )
printCertInfo( certificate );
}
/* Sign a cert request */
if( doSign )
{
CRYPT_CONTEXT signContext;
CRYPT_CERTIFICATE certificate, certRequest;
FILE *outFile;
BYTE buffer[ BUFFER_SIZE ];
int count;
/* Make sure the files are right */
if( keyFileName == NULL )
{
puts( "You must specify a keyfile to sign the cert object with." );
return( ERROR_BADARG );
}
if( argc <= 2 )
{
puts( "You need to specify an input file for the cert request "
"and and output file for the cert." );
return( ERROR_BADARG );
}
/* Get the private key and cert request */
status = getPrivateKey( &signContext, keyFileName, NULL );
if( cryptStatusError( status ) )
{
printf( "Couldn't get private key, error code = %d.\n", status );
return( -status );
}
status = importCertFile( &certRequest, argv[ 1 ] );
if( cryptStatusError( status ) )
{
cryptDestroyContext( signContext );
printf( "Couldn't import cert request, error code = %d.\n",
status );
return( -status );
}
/* Create the certificate from the cert request */
status = createCertificate( &certificate, optionFlag ? \
CRYPT_CERTTYPE_CERTCHAIN : CRYPT_CERTTYPE_CERTIFICATE,
certRequest, signContext );
cryptDestroyContext( signContext );
cryptDestroyCert( certRequest );
if( cryptStatusError( status ) )
{
printf( "Couldn't create certificate from cert request, error "
"code = %d.\n", status );
return( -status );
}
/* Export the cert and write it to the output file */
cryptExportCert( buffer, &count, optionFlag ? \
CRYPT_CERTFORMAT_CERTCHAIN : CRYPT_CERTFORMAT_CERTIFICATE,
certificate );
cryptDestroyCert( certificate );
if( ( outFile = fopen( argv[ 2 ], "wb" ) ) == NULL )
{
perror( argv[ 2 ] );
return( ERROR_FILE_INPUT );
}
fwrite( buffer, 1, count, outFile );
fclose( outFile );
}
/* Update a private key with a cert object */
if( doUpdate )
{
CRYPT_KEYSET cryptKeyset;
CRYPT_CERTIFICATE certificate;
/* Make sure the files are right */
if( keyFileName == NULL )
{
puts( "You must specify a keyfile to upate." );
return( ERROR_BADARG );
}
if( argc <= 1 )
{
puts( "You need to specify an input file to read the cert "
"object from." );
return( ERROR_BADARG );
}
/* Import the cert object */
status = importCertFile( &certificate, argv[ 1 ] );
if( cryptStatusError( status ) )
{
printf( "Couldn't import cert object, error code = %d.\n",
status );
return( -status );
}
/* Update the private key keyset with the cert object */
status = cryptKeysetOpen( &cryptKeyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE,
keyFileName, CRYPT_KEYOPT_NONE );
if( cryptStatusOK( status ) )
{
status = cryptGetPrivateKey( cryptKeyset, NULL, CRYPT_KEYID_NONE,
NULL, password );
if( cryptStatusOK( status ) )
status = cryptAddPrivateKey( cryptKeyset, certificate, NULL );
cryptKeysetClose( cryptKeyset );
}
if( cryptStatusError( status ) )
printf( "Couldn't update keyset with certificate object, error "
"code %d.\n", status );
}
/* Clean up. The cryptlib cleanup is handled by the atexit() function */
if( cryptStatusError( status ) )
{
printf( "Certificate processing failed with error code %d.\n",
status );
return( -status );
}
return( EXIT_SUCCESS );
}
#ifdef WRAP_STANDALONE
int main( int argc, char **argv )
{
char *args1[] = {
"", "-ks",
"-dC=US,O=Certificates R US,OU=Test CA,CN=John Doe,Email=doe@certsrus.com",
"c:/temp/cakey.der"
};
char *args2[] = {
"", "-k",
"-dC=US,O=Foo Bar and Grill,OU=Hamburgers,CN=Burger Bob",
"c:/temp/userkey.der"
};
char *args3[] = {
"", "-x", "-fc:/temp/userkey.der", "c:/temp/certreq.der"
};
char *args4[] = {
"", "-sc", "-fc:/temp/cakey.der", "c:/temp/certreq.der", "c:/temp/certchain.der"
};
char *args5[] = {
"", "-u", "-fc:/temp/userkey.der", "c:/temp/certchain.der"
};
/* Generate self-signed CA root */
wrappedMain( 4, args1 );
/* Generate user key and cert request */
wrappedMain( 4, args2 );
/* Extract cert request from user key */
wrappedMain( 4, args3 );
/* Sign cert request with CA root to give cert chain */
wrappedMain( 5, args4 );
/* Update user key with new cert chain */
wrappedMain( 4, args5 );
}
#endif /* WRAP_STANDALONE */
#endif /* STANDALONE_PROGRAM */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -