sslsample.c

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

C
620
字号
/* * 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. */#include "sslsample.h"#include "sslerror.h"/* Declare SSL cipher suites. */int cipherSuites[] = {	SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA,	SSL_FORTEZZA_DMS_WITH_RC4_128_SHA,	SSL_RSA_WITH_RC4_128_MD5,	SSL_RSA_WITH_3DES_EDE_CBC_SHA,	SSL_RSA_WITH_DES_CBC_SHA,	SSL_RSA_EXPORT_WITH_RC4_40_MD5,	SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,	SSL_FORTEZZA_DMS_WITH_NULL_SHA,	SSL_RSA_WITH_NULL_MD5,	0};int ssl2CipherSuites[] = {	SSL_EN_RC4_128_WITH_MD5,              /* A */	SSL_EN_RC4_128_EXPORT40_WITH_MD5,     /* B */	SSL_EN_RC2_128_CBC_WITH_MD5,          /* C */	SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */	SSL_EN_DES_64_CBC_WITH_MD5,           /* E */	SSL_EN_DES_192_EDE3_CBC_WITH_MD5,     /* F */	0};int ssl3CipherSuites[] = {	SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* a */	SSL_FORTEZZA_DMS_WITH_RC4_128_SHA,      /* b */	SSL_RSA_WITH_RC4_128_MD5,               /* c */	SSL_RSA_WITH_3DES_EDE_CBC_SHA,          /* d */	SSL_RSA_WITH_DES_CBC_SHA,               /* e */	SSL_RSA_EXPORT_WITH_RC4_40_MD5,         /* f */	SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,     /* g */	SSL_FORTEZZA_DMS_WITH_NULL_SHA,         /* h */	SSL_RSA_WITH_NULL_MD5,                  /* i */	SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,     /* j */	SSL_RSA_FIPS_WITH_DES_CBC_SHA,          /* k */	TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,    /* l */	TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,     /* m */	0};/**************************************************************************** ** SSL callback routines.****************************************************************************//* Function: char * myPasswd() *  * Purpose: This function is our custom password handler that is called by * SSL when retreiving private certs and keys from the database. Returns a * pointer to a string that with a password for the database. Password pointer * should point to dynamically allocated memory that will be freed later. */char *myPasswd(PK11SlotInfo *info, PRBool retry, void *arg){	char * passwd = NULL;	if ( (!retry) && arg ) {		passwd = PORT_Strdup((char *)arg);	}	return passwd;}/* Function: SECStatus myAuthCertificate() * * Purpose: This function is our custom certificate authentication handler. *  * Note: This implementation is essentially the same as the default  *       SSL_AuthCertificate(). */SECStatus myAuthCertificate(void *arg, PRFileDesc *socket,                   PRBool checksig, PRBool isServer) {	SECCertUsage        certUsage;	CERTCertificate *   cert;	void *              pinArg;	char *              hostName;	SECStatus           secStatus;	if (!arg || !socket) {		errWarn("myAuthCertificate");		return SECFailure;	}	/* Define how the cert is being used based upon the isServer flag. */	certUsage = isServer ? certUsageSSLClient : certUsageSSLServer;	cert = SSL_PeerCertificate(socket);		pinArg = SSL_RevealPinArg(socket);	secStatus = CERT_VerifyCertNow((CERTCertDBHandle *)arg,	                               cert,	                               checksig,	                               certUsage,	                               pinArg);	/* If this is a server, we're finished. */	if (isServer || secStatus != SECSuccess) {		return secStatus;	}	/* Certificate is OK.  Since this is the client side of an SSL	 * connection, we need to verify that the name field in the cert	 * matches the desired hostname.  This is our defense against	 * man-in-the-middle attacks.	 */	/* SSL_RevealURL returns a hostName, not an URL. */	hostName = SSL_RevealURL(socket);	if (hostName && hostName[0]) {		secStatus = CERT_VerifyCertName(cert, hostName);	} else {		PR_SetError(SSL_ERROR_BAD_CERT_DOMAIN, 0);		secStatus = SECFailure;	}	if (hostName)		PR_Free(hostName);	return secStatus;}/* Function: SECStatus myBadCertHandler() * * Purpose: This callback is called when the incoming certificate is not * valid. We define a certain set of parameters that still cause the * certificate to be "valid" for this session, and return SECSuccess to cause * the server to continue processing the request when any of these conditions * are met. Otherwise, SECFailure is return and the server rejects the  * request. */SECStatus myBadCertHandler(void *arg, PRFileDesc *socket) {    SECStatus	secStatus = SECFailure;    PRErrorCode	err;    /* log invalid cert here */    if (!arg) {		return secStatus;    }    *(PRErrorCode *)arg = err = PORT_GetError();    /* If any of the cases in the switch are met, then we will proceed   */    /* with the processing of the request anyway. Otherwise, the default */	    /* case will be reached and we will reject the request.              */    switch (err) {    case SEC_ERROR_INVALID_AVA:    case SEC_ERROR_INVALID_TIME:    case SEC_ERROR_BAD_SIGNATURE:    case SEC_ERROR_EXPIRED_CERTIFICATE:    case SEC_ERROR_UNKNOWN_ISSUER:    case SEC_ERROR_UNTRUSTED_CERT:    case SEC_ERROR_CERT_VALID:    case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:    case SEC_ERROR_CRL_EXPIRED:    case SEC_ERROR_CRL_BAD_SIGNATURE:    case SEC_ERROR_EXTENSION_VALUE_INVALID:    case SEC_ERROR_CA_CERT_INVALID:    case SEC_ERROR_CERT_USAGES_INVALID:    case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION:		secStatus = SECSuccess;	break;    default:		secStatus = SECFailure;	break;    }	printf("Bad certificate: %d, %s\n", err, SSL_Strerror(err));    return secStatus;}/* Function: SECStatus ownGetClientAuthData() * * Purpose: This callback is used by SSL to pull client certificate  * information upon server request. */SECStatus myGetClientAuthData(void *arg,                    PRFileDesc *socket,                    struct CERTDistNamesStr *caNames,                    struct CERTCertificateStr **pRetCert,                    struct SECKEYPrivateKeyStr **pRetKey) {    CERTCertificate *  cert;    SECKEYPrivateKey * privKey;    char *             chosenNickName = (char *)arg;    void *             proto_win      = NULL;    SECStatus          secStatus      = SECFailure;    proto_win = SSL_RevealPinArg(socket);    if (chosenNickName) {		cert = PK11_FindCertFromNickname(chosenNickName, proto_win);		if (cert) {		    privKey = PK11_FindKeyByAnyCert(cert, proto_win);		    if (privKey) {				secStatus = SECSuccess;		    } else {				CERT_DestroyCertificate(cert);		    }		}    } else { /* no nickname given, automatically find the right cert */		CERTCertNicknames *names;		int                i;		names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(), 		                              SEC_CERT_NICKNAMES_USER, proto_win);		if (names != NULL) {		    for(i = 0; i < names->numnicknames; i++ ) {				cert = PK11_FindCertFromNickname(names->nicknames[i], 				                                 proto_win);				if (!cert) {				    continue;				}				/* Only check unexpired certs */				if (CERT_CheckCertValidTimes(cert, PR_Now(), PR_FALSE)				      != secCertTimeValid ) {				    CERT_DestroyCertificate(cert);				    continue;				}				secStatus = NSS_CmpCertChainWCANames(cert, caNames);				if (secStatus == SECSuccess) {				    privKey = PK11_FindKeyByAnyCert(cert, proto_win);				    if (privKey) {						break;				    }				    secStatus = SECFailure;				    break;				}				CERT_FreeNicknames(names);		    } /* for loop */		}    }    if (secStatus == SECSuccess) {		*pRetCert = cert;		*pRetKey  = privKey;    }    return secStatus;}/* Function: SECStatus myHandshakeCallback() * * Purpose: Called by SSL to inform application that the handshake is * complete. This function is mostly used on the server side of an SSL * connection, although it is provided for a client as well. * Useful when a non-blocking SSL_RedoHandshake or SSL_ResetHandshake  * is used to initiate a handshake. * * A typical scenario would be: * * 1. Server accepts an SSL connection from the client without client auth. * 2. Client sends a request.

⌨️ 快捷键说明

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