certcgi.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,362 行 · 第 1/5 页

C
2,362
字号
    /* makes and encodes a certrequest */{    PK11SlotInfo             *slot;    CERTCertificateRequest   *certReq = NULL;    CERTSubjectPublicKeyInfo *spki;    SECKEYPrivateKey         *privkey = NULL;    SECKEYPublicKey          *pubkey = NULL;    CERTName                 *name;    char                     *key;    extern SECKEYPrivateKey  *privkeys[9];    int                      keySizeInBits;    char                     *challenge = "foo";    SECStatus                rv = SECSuccess;    PQGParams                *pqgParams = NULL;    PQGVerify                *pqgVfy = NULL;    name = CERT_AsciiToName(find_field(form_data, "subject", PR_TRUE));    if (name == NULL) {	error_out("ERROR: Unable to create Subject Name");    }    key = find_field(form_data, "key", PR_TRUE);    if (key == NULL) {	switch (*find_field(form_data, "keysize", PR_TRUE)) {	  case '0':	    keySizeInBits = 2048;	    break;	  case '1':	    keySizeInBits = 1024;	    break;	  case '2':	    keySizeInBits = 512;	    break;	  default:	    error_out("ERROR: Unsupported Key length selected");	}	if (find_field_bool(form_data, "keyType-dsa", PR_TRUE)) {	    rv = PQG_ParamGen(keySizeInBits, &pqgParams, &pqgVfy);	    if (rv != SECSuccess) {		error_out("ERROR: Unable to generate PQG parameters");	    }	    slot = PK11_GetBestSlot(CKM_DSA_KEY_PAIR_GEN, NULL);	    privkey = PK11_GenerateKeyPair(slot, CKM_DSA_KEY_PAIR_GEN, 					   pqgParams,&pubkey, PR_FALSE, 					   PR_TRUE, NULL);	} else {	    privkey = SECKEY_CreateRSAPrivateKey(keySizeInBits, &pubkey, NULL);	}	privkeys[which_priv_key] = privkey;	spki = SECKEY_CreateSubjectPublicKeyInfo(pubkey);    } else {	spki = SECKEY_ConvertAndDecodePublicKeyAndChallenge(key, challenge, 							    NULL);	if (spki == NULL) {	    error_out("ERROR: Unable to decode Public Key and Challenge String");	}    }    certReq = CERT_CreateCertificateRequest(name, spki, NULL);    if (certReq == NULL) {	error_out("ERROR: Unable to create Certificate Request");    }    if (pubkey != NULL) {	SECKEY_DestroyPublicKey(pubkey);    }    if (spki != NULL) {	SECKEY_DestroySubjectPublicKeyInfo(spki);    }    if (pqgParams != NULL) {	PQG_DestroyParams(pqgParams);    }    if (pqgVfy != NULL) {	PQG_DestroyVerify(pqgVfy);    }    return certReq;}static CERTCertificate *MakeV1Cert(CERTCertDBHandle        *handle, 	   CERTCertificateRequest  *req,	   char                    *issuerNameStr, 	   PRBool                  selfsign, 	   int                     serialNumber,	   int                     warpmonths,	   Pair                    *data){    CERTCertificate                 *issuerCert = NULL;    CERTValidity                    *validity;    CERTCertificate                 *cert = NULL;    PRExplodedTime                  printableTime;    PRTime                          now, 	                            after;    SECStatus rv;           if ( !selfsign ) {	issuerCert = CERT_FindCertByNameString(handle, issuerNameStr);	if (!issuerCert) {	    error_out("ERROR: Could not find issuer's certificate");	    return NULL;	}    }    if (find_field_bool(data, "manValidity", PR_TRUE)) {	rv = DER_AsciiToTime(&now, find_field(data, "notBefore", PR_TRUE));    } else {	now = PR_Now();    }    PR_ExplodeTime (now, PR_GMTParameters, &printableTime);    if ( warpmonths ) {	printableTime.tm_month += warpmonths;	now = PR_ImplodeTime (&printableTime);	PR_ExplodeTime (now, PR_GMTParameters, &printableTime);    }    if (find_field_bool(data, "manValidity", PR_TRUE)) {	rv = DER_AsciiToTime(&after, find_field(data, "notAfter", PR_TRUE));	PR_ExplodeTime (after, PR_GMTParameters, &printableTime);    } else {	printableTime.tm_month += 3;	after = PR_ImplodeTime (&printableTime);    }    /* note that the time is now in micro-second unit */    validity = CERT_CreateValidity (now, after);    if ( selfsign ) {	cert = CERT_CreateCertificate	    (serialNumber,&(req->subject), validity, req);    } else {	cert = CERT_CreateCertificate	    (serialNumber,&(issuerCert->subject), validity, req);    }        CERT_DestroyValidity(validity);    if ( issuerCert ) {	CERT_DestroyCertificate (issuerCert);    }    return(cert);}static intget_serial_number(Pair  *data){    int                 serial = 0;    int                 error;    char                *filename = SERIAL_FILE;    char                *SN;    FILE                *serialFile;    if (find_field_bool(data, "serial-auto", PR_TRUE)) {	serialFile = fopen(filename, "r");	if (serialFile != NULL) {	    fread(&serial, sizeof(int), 1, serialFile);	    if (ferror(serialFile) != 0) {		error_out("Error: Unable to read serial number file");	    }	    if (serial == 4294967295) {		serial = 21;	    }	    fclose(serialFile);	    ++serial;	    serialFile = fopen(filename,"w");	    if (serialFile == NULL) {	        error_out("ERROR: Unable to open serial number file for writing");	    }	    fwrite(&serial, sizeof(int), 1, serialFile);	    if (ferror(serialFile) != 0) {		error_out("Error: Unable to write to serial number file");	    }	} else {	    fclose(serialFile);	    serialFile = fopen(filename,"w");	    if (serialFile == NULL) {		error_out("ERROR: Unable to open serial number file");	    }	    serial = 21;	    fwrite(&serial, sizeof(int), 1, serialFile);	    if (ferror(serialFile) != 0) {		error_out("Error: Unable to write to serial number file");	    }	    error = ferror(serialFile);	    if (error != 0) {		error_out("ERROR: Unable to write to serial file");	    }	}	fclose(serialFile);    } else {	SN = find_field(data, "serial_value", PR_TRUE);	while (*SN != '\0') {	    serial = serial * 16;	    if ((*SN >= 'A') && (*SN <='F')) {		serial += *SN - 'A' + 10; 	    } else {		if ((*SN >= 'a') && (*SN <='f')) {		    serial += *SN - 'a' + 10;		} else {		    serial += *SN - '0';		}	    }	    ++SN;	}    }    return serial;}		       static CERTCertDBHandle*OpenCertDB(void)  /* NOTE: This routine has been modified to allow the libsec/pcertdb.c   * routines to automatically find and convert the old cert database   * into the new v3.0 format (cert db version 5).   */{    CERTCertDBHandle  *certHandle;    SECStatus         rv;    /* Allocate a handle to fill with CERT_OpenCertDB below */    certHandle = (CERTCertDBHandle *)PORT_ZAlloc(sizeof(CERTCertDBHandle));    if (!certHandle) {	error_out("ERROR: unable to get database handle");	return NULL;    }    rv = CERT_OpenCertDB(certHandle, PR_FALSE, SECU_CertDBNameCallback, NULL);    if (rv) {	error_out("ERROR: Could not open certificate database");	if (certHandle) free (certHandle);  /* we don't want to leave 					       anything behind... */	return NULL;    } else {	CERT_SetDefaultCertDB(certHandle);    }    return certHandle;}typedef SECStatus (* EXTEN_VALUE_ENCODER)		(PRArenaPool *extHandle, void *value, SECItem *encodedValue);static SECStatus EncodeAndAddExtensionValue(	PRArenaPool          *arena, 	void                 *extHandle, 	void                 *value, 	PRBool 		     criticality,	int 		     extenType, 	EXTEN_VALUE_ENCODER  EncodeValueFn){    SECItem                  encodedValue;    SECStatus                rv;	    encodedValue.data = NULL;    encodedValue.len = 0;    rv = (*EncodeValueFn)(arena, value, &encodedValue);    if (rv != SECSuccess) {	error_out("ERROR: Unable to encode extension value");    }    rv = CERT_AddExtension	(extHandle, extenType, &encodedValue, criticality, PR_TRUE);    return (rv);}static SECStatus AddKeyUsage (void  *extHandle, 	     Pair  *data){    SECItem        bitStringValue;    unsigned char  keyUsage = 0x0;    if (find_field_bool(data,"keyUsage-digitalSignature", PR_TRUE)){	keyUsage |= (0x80 >> 0);    }    if (find_field_bool(data,"keyUsage-nonRepudiation", PR_TRUE)){	keyUsage |= (0x80 >> 1);    }    if (find_field_bool(data,"keyUsage-keyEncipherment", PR_TRUE)){	keyUsage |= (0x80 >> 2);    }    if (find_field_bool(data,"keyUsage-dataEncipherment", PR_TRUE)){	keyUsage |= (0x80 >> 3);    }    if (find_field_bool(data,"keyUsage-keyAgreement", PR_TRUE)){	keyUsage |= (0x80 >> 4);    }    if (find_field_bool(data,"keyUsage-keyCertSign", PR_TRUE)) {	keyUsage |= (0x80 >> 5);    }    if (find_field_bool(data,"keyUsage-cRLSign", PR_TRUE)) {	keyUsage |= (0x80 >> 6);    }    bitStringValue.data = &keyUsage;    bitStringValue.len = 1;    return (CERT_EncodeAndAddBitStrExtension	    (extHandle, SEC_OID_X509_KEY_USAGE, &bitStringValue,	     (find_field_bool(data, "keyUsage-crit", PR_TRUE))));}static CERTOidSequence *CreateOidSequence(void){  CERTOidSequence *rv = (CERTOidSequence *)NULL;  PRArenaPool *arena = (PRArenaPool *)NULL;  arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);  if( (PRArenaPool *)NULL == arena ) {    goto loser;  }  rv = (CERTOidSequence *)PORT_ArenaZAlloc(arena, sizeof(CERTOidSequence));  if( (CERTOidSequence *)NULL == rv ) {    goto loser;  }  rv->oids = (SECItem **)PORT_ArenaZAlloc(arena, sizeof(SECItem *));  if( (SECItem **)NULL == rv->oids ) {    goto loser;  }  rv->arena = arena;  return rv; loser:  if( (PRArenaPool *)NULL != arena ) {    PORT_FreeArena(arena, PR_FALSE);  }  return (CERTOidSequence *)NULL;}static SECStatusAddOidToSequence(CERTOidSequence *os, SECOidTag oidTag){  SECItem **oids;  PRUint32 count = 0;  SECOidData *od;  od = SECOID_FindOIDByTag(oidTag);  if( (SECOidData *)NULL == od ) {    return SECFailure;  }  for( oids = os->oids; (SECItem *)NULL != *oids; oids++ ) {    count++;  }  /* ArenaZRealloc */  {    PRUint32 i;    oids = (SECItem **)PORT_ArenaZAlloc(os->arena, sizeof(SECItem *) * (count+2));    if( (SECItem **)NULL == oids ) {      return SECFailure;    }        for( i = 0; i < count; i++ ) {      oids[i] = os->oids[i];    }    /* ArenaZFree(os->oids); */  }  os->oids = oids;  os->oids[count] = &od->oid;  return SECSuccess;}static SECItem *EncodeOidSequence(CERTOidSequence *os){  SECItem *rv;  extern const SEC_ASN1Template CERT_OidSeqTemplate[];  rv = (SECItem *)PORT_ArenaZAlloc(os->arena, sizeof(SECItem));  if( (SECItem *)NULL == rv ) {    goto loser;  }  if( !SEC_ASN1EncodeItem(os->arena, rv, os, CERT_OidSeqTemplate) ) {    goto loser;  }  return rv; loser:  return (SECItem *)NULL;}static SECStatusAddExtKeyUsage(void *extHandle, Pair *data){  SECStatus rv;  CERTOidSequence *os;  SECItem *value;  PRBool crit;  os = CreateOidSequence();  if( (CERTOidSequence *)NULL == os ) {    return SECFailure;  }  if( find_field_bool(data, "extKeyUsage-serverAuth", PR_TRUE) ) {    rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_SERVER_AUTH);    if( SECSuccess != rv ) goto loser;  }  if( find_field_bool(data, "extKeyUsage-clientAuth", PR_TRUE) ) {    rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH);    if( SECSuccess != rv ) goto loser;  }  if( find_field_bool(data, "extKeyUsage-codeSign", PR_TRUE) ) {    rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_CODE_SIGN);    if( SECSuccess != rv ) goto loser;  }  if( find_field_bool(data, "extKeyUsage-emailProtect", PR_TRUE) ) {    rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT);    if( SECSuccess != rv ) goto loser;  }  if( find_field_bool(data, "extKeyUsage-timeStamp", PR_TRUE) ) {    rv = AddOidToSequence(os, SEC_OID_EXT_KEY_USAGE_TIME_STAMP);    if( SECSuccess != rv ) goto loser;  }  if( find_field_bool(data, "extKeyUsage-ocspResponder", PR_TRUE) ) {    rv = AddOidToSequence(os, SEC_OID_OCSP_RESPONDER);    if( SECSuccess != rv ) goto loser;  }  if( find_field_bool(data, "extKeyUsage-NS-govtApproved", PR_TRUE) ) {    rv = AddOidToSequence(os, SEC_OID_NS_KEY_USAGE_GOVT_APPROVED);    if( SECSuccess != rv ) goto loser;  }  value = EncodeOidSequence(os);  crit = find_field_bool(data, "extKeyUsage-crit", PR_TRUE);  rv = CERT_AddExtension(extHandle, SEC_OID_X509_EXT_KEY_USAGE, value,                         crit, PR_TRUE);  /*FALLTHROUGH*/ loser:  CERT_DestroyOidSequence(os);  return rv;}static SECStatusAddSubKeyID(void             *extHandle, 	    Pair             *data, 	    CERTCertificate  *subjectCert){    SECItem                  encodedValue;    SECStatus                rv;    char                     *read;    char                     *write;    char                     *first;    char                     character;    int                      high_digit = 0,	                     low_digit = 0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?