⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 certutil.c

📁 支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS #11, PKCS #12, S/MIME, X.509v3证书等安全协议或标准的开发库编译用到NSPR
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape security libraries. *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//*** certutil.c**** utility for managing certificates and the cert database***/#include <stdio.h>#include <string.h>#if defined(WIN32)#include "fcntl.h"#include "io.h"#endif#include "secutil.h"#if defined(XP_UNIX)#include <unistd.h>#endif#include "nspr.h"#include "prtypes.h"#include "prtime.h"#include "prlong.h"#include "pk11func.h"#include "secasn1.h"#include "cert.h"#include "cryptohi.h"#include "secoid.h"#include "certdb.h"#include "cdbhdl.h"/* SEC_Init is now declared in secutil.h *//* We really should convert to using NSS, but it doesn't provide all * of the functionality we need (like opening the databases writeable). */#define MIN_KEY_BITS		512#define MAX_KEY_BITS		2048#define DEFAULT_KEY_BITS	1024#define GEN_BREAK(e) rv=e; break;extern SECKEYPrivateKey *CERTUTIL_GeneratePrivateKey(KeyType keytype,						     PK11SlotInfo *slot,                                                      int rsasize,						     int publicExponent,						     char *noise,						     SECKEYPublicKey **pubkeyp,						     char *pqgFile,                                                     char *passFile);static char *progName;static CERTGeneralName *GetGeneralName (PRArenaPool *arena){    CERTGeneralName *namesList = NULL;    CERTGeneralName *current;    CERTGeneralName *tail = NULL;    SECStatus rv = SECSuccess;    int intValue;    char buffer[512];    void *mark;    PORT_Assert (arena);    mark = PORT_ArenaMark (arena);    do {	puts ("\nSelect one of the following general name type: \n");	puts ("\t1 - instance of other name\n\t2 - rfc822Name\n\t3 - dnsName\n");	puts ("\t4 - x400Address\n\t5 - directoryName\n\t6 - ediPartyName\n");	puts ("\t7 - uniformResourceidentifier\n\t8 - ipAddress\n\t9 - registerID\n");	puts ("\tOther - omit\n\t\tChoice:");	scanf ("%d", &intValue);	if (intValue >= certOtherName || intValue <= certRegisterID) {	    if (namesList == NULL) {		namesList = current = tail = (CERTGeneralName *) PORT_ArenaAlloc 		                                  (arena, sizeof (CERTGeneralName));	    } else {		current = (CERTGeneralName *) PORT_ArenaAlloc(arena, 							      sizeof (CERTGeneralName));	    }	    if (current == NULL) {		GEN_BREAK (SECFailure);	    }		} else {	    break;	}	current->type = intValue;	puts ("\nEnter data:");	fflush (stdout);	gets (buffer);	switch (current->type) {	    case certURI:	    case certDNSName:	    case certRFC822Name:		current->name.other.data = PORT_ArenaAlloc (arena, strlen (buffer));		if (current->name.other.data == NULL) {		    GEN_BREAK (SECFailure);		}		PORT_Memcpy		  (current->name.other.data, buffer, current->name.other.len = strlen(buffer));		break;	    case certEDIPartyName:	    case certIPAddress:	    case certOtherName:	    case certRegisterID:	    case certX400Address: {		current->name.other.data = PORT_ArenaAlloc (arena, strlen (buffer) + 2);		if (current->name.other.data == NULL) {		    GEN_BREAK (SECFailure);		}		PORT_Memcpy (current->name.other.data + 2, buffer, strlen (buffer));		/* This may not be accurate for all cases.  For now, use this tag type */		current->name.other.data[0] = (char)(((current->type - 1) & 0x1f)| 0x80);		current->name.other.data[1] = (char)strlen (buffer);		current->name.other.len = strlen (buffer) + 2;		break;	    }	    case certDirectoryName: {		CERTName *directoryName = NULL;		directoryName = CERT_AsciiToName (buffer);		if (!directoryName) {		    fprintf(stderr, "certutil: improperly formatted name: \"%s\"\n", buffer);		    break;		}			    		rv = CERT_CopyName (arena, &current->name.directoryName, directoryName);		CERT_DestroyName (directoryName);				break;	    }	}	if (rv != SECSuccess)	    break;	current->l.next = &(namesList->l);	current->l.prev = &(tail->l);	tail->l.next = &(current->l);	tail = current;    }while (1);    if (rv != SECSuccess) {	PORT_SetError (rv);	PORT_ArenaRelease (arena, mark);	namesList = NULL;    }    return (namesList);}static SECStatus GetString(PRArenaPool *arena, char *prompt, SECItem *value){    char buffer[251];    value->data = NULL;    value->len = 0;        puts (prompt);    gets (buffer);    if (strlen (buffer) > 0) {	value->data = PORT_ArenaAlloc (arena, strlen (buffer));	if (value->data == NULL) {	    PORT_SetError (SEC_ERROR_NO_MEMORY);	    return (SECFailure);	}	PORT_Memcpy (value->data, buffer, value->len = strlen(buffer));    }    return (SECSuccess);}static CERTCertificateRequest *GetCertRequest(PRFileDesc *inFile){    CERTCertificateRequest *certReq = NULL;    CERTSignedData signedData;    PRArenaPool *arena = NULL;    SECItem reqDER;    SECStatus rv;    reqDER.data = NULL;    do {	arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);	if (arena == NULL) {	    GEN_BREAK (SEC_ERROR_NO_MEMORY);	}	 	rv = SECU_ReadDERFromFile(&reqDER, inFile, PR_FALSE);	if (rv) 	    break;        certReq = (CERTCertificateRequest*) PORT_ArenaZAlloc		  (arena, sizeof(CERTCertificateRequest));        if (!certReq) 	    break;	certReq->arena = arena;	/* Since cert request is a signed data, must decode to get the inner	   data	 */	PORT_Memset(&signedData, 0, sizeof(signedData));	rv = SEC_ASN1DecodeItem(arena, &signedData, CERT_SignedDataTemplate, 				&reqDER);	if (rv)	    break;	        rv = SEC_ASN1DecodeItem(arena, certReq, CERT_CertificateRequestTemplate,				&signedData.data);   } while (0);   if (rv) {       PRErrorCode  perr = PR_GetError();       fprintf(stderr, "%s: unable to decode DER cert request (%s)\n", progName,               SECU_Strerror(perr));   }   return (certReq);}static PRBool GetYesNo(char *prompt) {    char buf[3];    PR_Sync(PR_STDIN);    PR_Write(PR_STDOUT, prompt, strlen(prompt)+1);    PR_Read(PR_STDIN, buf, sizeof(buf));    return (buf[0] == 'y' || buf[0] == 'Y') ? PR_TRUE : PR_FALSE;#if 0    char charValue;    puts (prompt);    scanf ("%c", &charValue);    if (charValue != 'y' && charValue != 'Y')	return (0);    return (1);#endif}static SECStatusAddCert(PK11SlotInfo *slot, CERTCertDBHandle *handle, char *name, char *trusts,         PRFileDesc *inFile, PRBool ascii, PRBool emailcert){    CERTCertTrust *trust = NULL;    CERTCertificate *cert = NULL, *tempCert = NULL;    SECItem certDER;    SECStatus rv;    certDER.data = NULL;    do {	/* Read in the entire file specified with the -i argument */	rv = SECU_ReadDERFromFile(&certDER, inFile, ascii);	if (rv != SECSuccess) {	    SECU_PrintError(progName, "unable to read input file");	    break;	}	/* Read in an ASCII cert and return a CERTCertificate */	cert = CERT_DecodeCertFromPackage((char *)certDER.data, certDER.len);	if (!cert) {	    SECU_PrintError(progName, "could not obtain certificate from file"); 	    GEN_BREAK(SECFailure);	}	/* Create a cert trust to pass to SEC_AddPermCertificate */	trust = (CERTCertTrust *)PORT_ZAlloc(sizeof(CERTCertTrust));	if (!trust) {	    SECU_PrintError(progName, "unable to allocate cert trust");	    GEN_BREAK(SECFailure);	}	rv = CERT_DecodeTrustString(trust, trusts);	if (rv) {	    SECU_PrintError(progName, "unable to decode trust string");	    GEN_BREAK(SECFailure);	}	/* CERT_ImportCert only collects certificates and returns the	* first certficate.  It does not insert these certificates into	* the dbase.  For now, just call CERT_NewTempCertificate.	* This will result in decoding the der twice.  This have to	* be handle properly.	*/	tempCert = CERT_NewTempCertificate(handle, &cert->derCert, NULL,	                                   PR_FALSE, PR_TRUE);	if (!PK11_IsInternal(slot)) {	    tempCert->trust = trust;	    rv = PK11_ImportCertForKeyToSlot(slot, tempCert, name,	                                     PR_FALSE, NULL);	}	if (tempCert == NULL) {	    SECU_PrintError(progName,"unable to add cert to the temp database");	    GEN_BREAK(SECFailure);	}	rv = CERT_AddTempCertToPerm(tempCert, name, trust);	if (rv) {	    SECU_PrintError(progName, "could not add certificate to database");	    GEN_BREAK(SECFailure);	}	if ( emailcert )	    CERT_SaveSMimeProfile(tempCert, NULL, NULL);    } while (0);    CERT_DestroyCertificate (tempCert);    CERT_DestroyCertificate (cert);    PORT_Free(trust);    PORT_Free(certDER.data);    return rv;}static SECStatusCertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,	CERTName *subject, char *phone, int ascii, PRFileDesc *outFile){    CERTSubjectPublicKeyInfo *spki;    CERTCertificateRequest *cr;    SECItem *encoding;    SECItem result;    SECStatus rv;    PRArenaPool *arena;    PRInt32 numBytes;    /* Create info about public key */    spki = SECKEY_CreateSubjectPublicKeyInfo(pubk);    if (!spki) {	SECU_PrintError(progName, "unable to create subject public key");	return SECFailure;    }    /* Generate certificate request */    cr = CERT_CreateCertificateRequest(subject, spki, 0);    if (!cr) {	SECU_PrintError(progName, "unable to make certificate request");	return SECFailure;    }    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( !arena ) {	SECU_PrintError(progName, "out of memory");	return SECFailure;    }        /* Der encode the request */    encoding = SEC_ASN1EncodeItem(arena, NULL, cr,				  CERT_CertificateRequestTemplate);    if (encoding == NULL) {	SECU_PrintError(progName, "der encoding of request failed");	return SECFailure;    }    /* Sign the request */    switch (keyType) {    case rsaKey:	rv = SEC_DerSignData(arena, &result, encoding->data, encoding->len, 	                     privk, SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION);	break;    case dsaKey:	rv = SEC_DerSignData(arena, &result, encoding->data, encoding->len, 	                 privk, SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST);	break;    default:	SECU_PrintError(progName, "Must use rsa or dsa key type");	return SECFailure;    }    if (rv) {	SECU_PrintError(progName, "signing of data failed");	return SECFailure;    }    /* Encode request in specified format */    if (ascii) {	char *obuf;	char *name, *email, *org, *state, *country;	SECItem *it;	int total;	it = &result;	obuf = BTOA_ConvertItemToAscii(it);	total = PL_strlen(obuf);	name = CERT_GetCommonName(subject);	if (!name) {	    fprintf(stderr, "You must specify a common name\n");	    return SECFailure;	}	if (!phone)	    phone = strdup("(not specified)");	email = CERT_GetCertEmailAddress(subject);	if (!email)	    email = strdup("(not specified)");	org = CERT_GetOrgName(subject);	if (!org)	    org = strdup("(not specified)");	state = CERT_GetStateName(subject);	if (!state)	    state = strdup("(not specified)");	country = CERT_GetCountryName(subject);	if (!country)	    country = strdup("(not specified)");	PR_fprintf(outFile, 	           "\nCertificate request generated by Netscape certutil\n");	PR_fprintf(outFile, "Phone: %s\n\n", phone);	PR_fprintf(outFile, "Common Name: %s\n", name);	PR_fprintf(outFile, "Email: %s\n", email);	PR_fprintf(outFile, "Organization: %s\n", org);

⌨️ 快捷键说明

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