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

📄 secutil.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. *//*** secutil.c - various functions used by security stuff***/#include "prtypes.h"#include "prtime.h"#include "prlong.h"#include "prerror.h"#include "prprf.h"#include "plgetopt.h"#include "secutil.h"#include "secpkcs7.h"#include <sys/stat.h>#include <stdarg.h>#ifdef XP_UNIX#include <unistd.h>#endif/* for SEC_TraverseNames */#include "cert.h"#include "certt.h"#include "certdb.h"#include "cdbhdl.h"#include "secmod.h"#include "pk11func.h"#include "secoid.h"#include "blapi.h"	/* for RNG_RNGInit */static char consoleName[] =  {#ifdef XP_UNIX    "/dev/tty"#else    "CON:"#endif};char *SECU_GetString(int16 error_number){    static char errString[80];    sprintf(errString, "Unknown error string (%d)", error_number);    return errString;}void SECU_PrintError(char *progName, char *msg, ...){    va_list args;    PRErrorCode err = PORT_GetError();    const char * errString = SECU_Strerror(err);    va_start(args, msg);    fprintf(stderr, "%s: ", progName);    vfprintf(stderr, msg, args);    if (errString != NULL && PORT_Strlen(errString) > 0)	fprintf(stderr, ": %s\n", errString);    else	fprintf(stderr, "\n");    va_end(args);}voidSECU_PrintSystemError(char *progName, char *msg, ...){    va_list args;    va_start(args, msg);    fprintf(stderr, "%s: ", progName);    vfprintf(stderr, msg, args);    fprintf(stderr, ": %s\n", strerror(errno));    va_end(args);}static voidsecu_ClearPassword(char *p){    if (p) {	PORT_Memset(p, 0, PORT_Strlen(p));	PORT_Free(p);    }}static SECItem *secu_GetZeroLengthPassword(SECKEYKeyDBHandle *handle){    SECItem *pwitem;    SECStatus rv;    /* hash the empty string as a password */    pwitem = SECKEY_DeriveKeyDBPassword(handle, "");    if (pwitem == NULL) {	return NULL;    }    /* check to see if this is the right password */    rv = SECKEY_CheckKeyDBPassword(handle, pwitem);    if (rv == SECFailure) {	return NULL;    }    return pwitem;}char *SECU_GetPasswordString(void *arg, char *prompt){#ifndef _WINDOWS    char *p = NULL;    FILE *input, *output;    /* open terminal */    input = fopen(consoleName, "r");    if (input == NULL) {	fprintf(stderr, "Error opening input terminal for read\n");	return NULL;    }    output = fopen(consoleName, "w");    if (output == NULL) {	fprintf(stderr, "Error opening output terminal for write\n");	return NULL;    }    p = SEC_GetPassword (input, output, prompt, SEC_BlindCheckPassword);            fclose(input);    fclose(output);    return p;#else    /* Win32 version of above. opening the console may fail       on windows95, and certainly isn't necessary.. */    char *p = NULL;    p = SEC_GetPassword (stdin, stdout, prompt, SEC_BlindCheckPassword);    return p;#endif}SECItem *SECU_GetPassword(void *arg, SECKEYKeyDBHandle *handle){    char *p = NULL;    SECStatus rv;    SECItem *pwitem;    /* Check to see if zero length password or not */    pwitem = secu_GetZeroLengthPassword(handle);    if (pwitem) {	return pwitem;    }    p = SECU_GetPasswordString(arg,"Password: ");    /* Check to see if zero length password or not */    pwitem = secu_GetZeroLengthPassword(handle);    if (pwitem) {	return pwitem;    }    /* hash the password */    pwitem = SECKEY_DeriveKeyDBPassword(handle, p);        /* clear out the password strings */    secu_ClearPassword(p);        if ( pwitem == NULL ) {	fprintf(stderr, "Error hashing password\n");	return NULL;    }    /* confirm the password */    rv = SECKEY_CheckKeyDBPassword(handle, pwitem);    if (rv) {	fprintf(stderr, "Sorry\n");	SECITEM_ZfreeItem(pwitem, PR_TRUE);	return NULL;    }        return pwitem;}/* *  p a s s w o r d _ h a r d c o d e  * *  A function to use the password passed in the -f(pwfile) argument *  of the command line.   *  After use once, null it out otherwise PKCS11 calls us forever.? * */char *SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg){    unsigned char phrase[200];    PRFileDesc *fd;    PRInt32 nb;    char *pwFile = arg;    int i;    if (!pwFile)	return 0;    if (retry) {	return 0;  /* no good retrying - the files contents will be the same */    }      fd = PR_Open(pwFile, PR_RDONLY, 0);    if (!fd) {	fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);	return NULL;    }    nb = PR_Read(fd, phrase, sizeof(phrase));      PR_Close(fd);    /* handle the Windows EOL case */    i = 0;    while (phrase[i] != '\r' && phrase[i] != '\n' && i < nb) i++;    phrase[i] = '\0';    if (nb == 0) {	fprintf(stderr,"password file contains no data\n");	return NULL;    } else {	return (char*) PORT_Strdup((char*)phrase);    }    return (char*) PORT_Strdup((char*)phrase);}char *SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg) {    char prompt[255];    secuPWData *pwdata = arg;    secuPWData pwnull = { PW_NONE, 0 };    if (arg == NULL)	pwdata = &pwnull;    if (retry && pwdata->source != PW_NONE) {	PR_fprintf(PR_STDERR, "incorrect password entered at command line.\n");    	return NULL;    }    sprintf(prompt, "Enter Password or Pin for \"%s\":",	    PK11_GetTokenName(slot));    switch (pwdata->source) {    case PW_NONE:	return SECU_GetPasswordString(NULL, prompt);    case PW_FROMFILE:	return SECU_FilePasswd(slot, retry, pwdata->data);    case PW_PLAINTEXT:	return PL_strdup(arg);    default:	break;    }    return NULL;}char *secu_InitSlotPassword(PK11SlotInfo *slot, PRBool retry, void *arg){    char *p0 = NULL;    char *p1 = NULL;    FILE *input, *output;    secuPWData *pwdata = arg;    if (pwdata->source == PW_NONE) {	/* open terminal */#ifdef _WINDOWS	input = stdin;#else	input = fopen(consoleName, "r");#endif	if (input == NULL) {	    PR_fprintf(PR_STDERR, "Error opening input terminal for read\n");	    return NULL;	}	/* we have no password, so initialize database with one */	PR_fprintf(PR_STDERR,                    "In order to finish creating your database, you\n");	PR_fprintf(PR_STDERR, "must enter a password which will be used to\n");	PR_fprintf(PR_STDERR, "encrypt this key and any future keys.\n\n");	PR_fprintf(PR_STDERR, 	           "The password must be at least 8 characters long,\n");	PR_fprintf(PR_STDERR, "and must contain at least one non-alphabetic ");	PR_fprintf(PR_STDERR, "character.\n\n");    } else if (pwdata->source == PW_FROMFILE) {	input = fopen(pwdata->data, "r");	if (input == NULL) {	    PR_fprintf(PR_STDERR, "Error opening \"%s\" for read\n",	                           pwdata->data);	    return NULL;	}    } else {	p0 = PL_strdup(pwdata->data);    }    output = fopen(consoleName, "w");    if (output == NULL) {	PR_fprintf(PR_STDERR, "Error opening output terminal for write\n");	return NULL;    }    for (;;) {	if (!p0) {	    p0 = SEC_GetPassword(input, output, "Enter new password: ",			         SEC_BlindCheckPassword);	}	if (pwdata->source == PW_NONE) {	    p1 = SEC_GetPassword(input, output, "Re-enter password: ",				 SEC_BlindCheckPassword);	}	if (pwdata->source != PW_NONE || (PORT_Strcmp(p0, p1) == 0)) {	    break;	}	PR_fprintf(PR_STDERR, "Passwords do not match. Try again.\n");    }            /* clear out the duplicate password string */    secu_ClearPassword(p1);        fclose(input);    fclose(output);    return p0;}SECStatusSECU_ChangePW(PK11SlotInfo *slot, char *passwd, char *pwFile){    SECStatus rv;    secuPWData pwdata, newpwdata;    char *oldpw = NULL, *newpw = NULL;    if (passwd) {	pwdata.source = PW_PLAINTEXT;	pwdata.data = passwd;    } else if (pwFile) {	pwdata.source = PW_FROMFILE;	pwdata.data = pwFile;    } else {	pwdata.source = PW_NONE;	pwdata.data = NULL;    }    if (PK11_NeedUserInit(slot)) {	newpw = secu_InitSlotPassword(slot, PR_FALSE, &pwdata);	rv = PK11_InitPin(slot, (char*)NULL, newpw);	goto done;    }    for (;;) {	oldpw = SECU_GetModulePassword(slot, PR_FALSE, &pwdata);	if (PK11_CheckUserPassword(slot, oldpw) != SECSuccess) {	    if (pwdata.source == PW_NONE) {		PR_fprintf(PR_STDERR, "Invalid password.  Try again.\n");	    } else {		PR_fprintf(PR_STDERR, "Invalid password.\n");		PORT_Memset(oldpw, 0, PL_strlen(oldpw));		PORT_Free(oldpw);		return SECFailure;	    }	} else	    break;	PORT_Free(oldpw);    }    newpwdata.source = PW_NONE;    newpwdata.data = NULL;    newpw = secu_InitSlotPassword(slot, PR_FALSE, &newpwdata);    if (PK11_ChangePW(slot, oldpw, newpw) != SECSuccess) {	PR_fprintf(PR_STDERR, "Failed to change password.\n");	return SECFailure;    }    PORT_Memset(oldpw, 0, PL_strlen(oldpw));    PORT_Free(oldpw);    PR_fprintf(PR_STDOUT, "Password changed successfully.\n");done:    PORT_Memset(newpw, 0, PL_strlen(newpw));    PORT_Free(newpw);    return SECSuccess;}struct matchobj {    SECItem index;    char *nname;    PRBool found;};static SECStatussecu_match_nickname(DBT *k, DBT *d, void *pdata){    struct matchobj *match;    unsigned char *buf;    char *nname;    int nnlen;    match = (struct matchobj *)pdata;    buf = (unsigned char *)d->data;    if (match->found == PR_TRUE)	return SECSuccess;    nnlen = buf[2];    nname = (char *)(buf + 3 + buf[1]);    if (PORT_Strncmp(match->nname, nname, nnlen) == 0) {	match->index.len = k->size;	match->index.data = PORT_ZAlloc(k->size + 1);	PORT_Memcpy(match->index.data, k->data, k->size);	match->found = PR_TRUE;    }    return SECSuccess;}SECItem *SECU_GetKeyIDFromNickname(char *name){    struct matchobj match;    SECKEYKeyDBHandle *handle;    SECItem *keyid;    match.nname = name;    match.found = PR_FALSE;    handle = SECKEY_GetDefaultKeyDB();    SECKEY_TraverseKeys(handle, secu_match_nickname, &match);    if (match.found == PR_FALSE)	return NULL;    keyid = SECITEM_DupItem(&match.index);    return keyid;}PRBoolSECU_CheckKeyNameExists(SECKEYKeyDBHandle *handle, char *nickname){    SECItem *keyid;    keyid = SECU_GetKeyIDFromNickname(nickname);    if(keyid == NULL)	return PR_FALSE;    SECITEM_FreeItem(keyid, PR_TRUE);    return PR_TRUE;}SECKEYPrivateKey *SECU_FindPrivateKeyFromNickname(char *name){    SECItem *         keyid;    SECKEYPrivateKey *key;    PK11SlotInfo *    slot = PK11_GetInternalKeySlot();    SECStatus         rv;    keyid = SECU_GetKeyIDFromNickname(name);    if (keyid == NULL)	return NULL;    PK11_SetPasswordFunc(SECU_GetModulePassword);    if(PK11_NeedLogin(slot) && !PK11_IsLoggedIn(slot,NULL)) {	rv = PK11_DoPassword(slot, PR_TRUE, NULL);	if (rv != SECSuccess)	    return NULL;    }    key = PK11_FindKeyByKeyID(slot, keyid, NULL);    SECITEM_FreeItem(keyid, PR_TRUE);    return key;}

⌨️ 快捷键说明

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