Esempio n. 1
0
/*
 * Callback from SSL for checking certificate the peer (other end of
 * the socket) presents.
 */
SECStatus
JSSL_DefaultCertAuthCallback(void *arg, PRFileDesc *fd, PRBool checkSig,
             PRBool isServer)
{
    char *          hostname = NULL;
    SECStatus         rv    = SECFailure;
    SECCertUsage      certUsage;
    CERTCertificate   *peerCert=NULL;

    certUsage = isServer ? certUsageSSLClient : certUsageSSLServer;
 

    /* SSL_PeerCertificate() returns a shallow copy of the cert, so we
       must destroy it before we exit this function */

    peerCert   = SSL_PeerCertificate(fd);

    if (peerCert) {
        rv = CERT_VerifyCertNow(CERT_GetDefaultCertDB(), peerCert,
                checkSig, certUsage, NULL /*pinarg*/);
    }

    /* if we're a server, then we don't need to check the CN of the
       certificate, so we can just return whatever returncode we
       have now
     */

    if ( rv != SECSuccess || isServer )  {
        if (peerCert) CERT_DestroyCertificate(peerCert);
            return (int)rv;
        }

    /* cert is OK.  This is the client side of an SSL connection.
     * Now check the name field in the cert against the desired hostname.
     * NB: This is our only defense against Man-In-The-Middle (MITM) attacks!
     */
    hostname = SSL_RevealURL(fd);    /* really is a hostname, not a URL */
    if (hostname && hostname[0]) {
        rv = CERT_VerifyCertName(peerCert, hostname);
        PORT_Free(hostname); 
    } else
        rv = SECFailure;

    if (peerCert) CERT_DestroyCertificate(peerCert);
    return rv;
}
Esempio n. 2
0
SECStatus
SSL_AuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer)
{
    SECStatus          rv;
    CERTCertDBHandle * handle;
    sslSocket *        ss;
    SECCertUsage       certUsage;
    const char *             hostname    = NULL;
    
    ss = ssl_FindSocket(fd);
    PORT_Assert(ss != NULL);
    if (!ss) {
	return SECFailure;
    }

    handle = (CERTCertDBHandle *)arg;

    /* this may seem backwards, but isn't. */
    certUsage = isServer ? certUsageSSLClient : certUsageSSLServer;

    rv = CERT_VerifyCertNow(handle, ss->sec.peerCert, checkSig, certUsage,
			    ss->pkcs11PinArg);

    if ( rv != SECSuccess || isServer )
	return rv;
  
    /* cert is OK.  This is the client side of an SSL connection.
     * Now check the name field in the cert against the desired hostname.
     * NB: This is our only defense against Man-In-The-Middle (MITM) attacks!
     */
    hostname = ss->url;
    if (hostname && hostname[0])
	rv = CERT_VerifyCertName(ss->sec.peerCert, hostname);
    else 
	rv = SECFailure;
    if (rv != SECSuccess)
	PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);

    return rv;
}
Esempio n. 3
0
static int
verify1(struct message *m, int n)
{
	SECItem	**digests;
	NSSCMSMessage	*msg;
	PLArenaPool	*poolp;
	SECAlgorithmID	**algids;
	CERTCertDBHandle	*handle;
	int	nlevels, i;
	int	status = 0;
	int	foundsender = 0;
	char	*sender;

	if ((m = getsig(m, n, &msg)) == NULL)
		return 1;
	sender = getsender(m);
	handle = CERT_GetDefaultCertDB();
	nlevels = NSS_CMSMessage_ContentLevelCount(msg);
	for (i = 0; i < nlevels; i++) {
		NSSCMSContentInfo	*content;
		SECOidTag	tag;

		content = NSS_CMSMessage_ContentLevel(msg, i);
		tag = NSS_CMSContentInfo_GetContentTypeTag(content);
		if (tag == SEC_OID_PKCS7_SIGNED_DATA) {
			NSSCMSSignedData	*data;
			int	nsigners, j;

			if ((data = NSS_CMSContentInfo_GetContent(content))
					== NULL) {
				fprintf(stderr, "Signed data missing for "
						"message %d.\n", n);
				status = -1;
				break;
			}
			if (!NSS_CMSSignedData_HasDigests(data)) {
				algids = NSS_CMSSignedData_GetDigestAlgs(data);
				if (getdig(m, n, &digests, &poolp, algids)
						!= OKAY) {
					status = -1;
					break;
				}
				if (NSS_CMSSignedData_SetDigests(data, algids,
							digests)
						!= SECSuccess) {
					fprintf(stderr, "Cannot set digests "
							"for message %d.\n", n);
					status = -1;
					break;
				}
				PORT_FreeArena(poolp, PR_FALSE);
			}
			if (NSS_CMSSignedData_ImportCerts(data, handle,
						certUsageEmailSigner,
						PR_FALSE) != SECSuccess) {
				fprintf(stderr, "Cannot temporarily import "
						"certificates for "
						"message %d.\n", n);
				status = -1;
				break;
			}
			nsigners = NSS_CMSSignedData_SignerInfoCount(data);
			if (nsigners == 0) {
				fprintf(stderr, "Message %d has no signers.\n",
						n);
				status = -1;
				break;
			}
			if (!NSS_CMSSignedData_HasDigests(data)) {
				fprintf(stderr, "Message %d has no digests.\n",
						n);
				status = -1;
				break;
			}
			for (j = 0; j < nsigners; j++) {
				const char	*svs;
				NSSCMSSignerInfo	*info;
				NSSCMSVerificationStatus	vs;
				SECStatus	bad;
				CERTCertificate	*cert;
				const char	*addr;
				int	passed = 0;

				info = NSS_CMSSignedData_GetSignerInfo(data, j);
				cert = NSS_CMSSignerInfo_GetSigningCertificate
					(info, handle);
				bad = NSS_CMSSignedData_VerifySignerInfo(data,
						j, handle,
						certUsageEmailSigner);
				vs = NSS_CMSSignerInfo_GetVerificationStatus
					(info);
				svs = NSS_CMSUtil_VerificationStatusToString
					(vs);
				addr = CERT_GetCertEmailAddress(&cert->subject);
				if (sender != NULL && addr != NULL &&
						asccasecmp(sender, addr) == 0)
					foundsender++;
				else {
					addr = CERT_GetFirstEmailAddress(cert);
					while (sender && addr) {
						if (!asccasecmp(sender, addr)) {
							foundsender++;
							break;
						}
						addr = CERT_GetNextEmailAddress
							(cert, addr);
					}
				}
				if (CERT_VerifyCertNow(handle,
						cert, PR_TRUE,
						certUsageEmailSigner,
						NULL) != SECSuccess)
					fprintf(stderr, "Bad certificate for "
							"signer <%s> of "
							"message %d: %s.\n",
							addr ? addr : "?", n,
							bad_cert_str());
				else
					passed++;
				if (bad)
					fprintf(stderr, "Bad status for "
							"signer <%s> of "
							"message %d: %s.\n",
							addr ? addr : "?",
							n, svs);
				else
					passed++;
				if (passed < 2)
					status = -1;
				else if (status == 0)
					status = 1;
			}
		}
	}
	if (foundsender == 0) {
		if (sender) {
			fprintf(stderr, "Signers of message "
					"%d do not include the sender <%s>\n",
				n, sender);
			status = -1;
		} else
			fprintf(stderr, "Warning: Message %d has no From: "
					"header field.\n", n);
	} else if (status == 1)
		printf("Message %d was verified successfully.\n", n);
	if (status == 0)
		fprintf(stderr, "No verification information found in "
				"message %d.\n", n);
	NSS_CMSMessage_Destroy(msg);
	return status != 1;
}
Esempio n. 4
0
/********************************************************************
 *
 * c e r t _ t r a v _ c a l l b a c k
 */
static SECStatus
cert_trav_callback(CERTCertificate *cert, SECItem *k, void *data)
{
    int list_certs = 1;
    char *name;

    if (data) {
        list_certs = *((int *)data);
    }

#define LISTING_USER_SIGNING_CERTS (list_certs == 1)
#define LISTING_ALL_CERTS (list_certs == 2)

    name = cert->nickname;
    if (name) {
        int isSigningCert;

        isSigningCert = cert->nsCertType & NS_CERT_TYPE_OBJECT_SIGNING;
        if (!isSigningCert && LISTING_USER_SIGNING_CERTS)
            return (SECSuccess);

        /* Display this name or email address */
        num_trav_certs++;

        if (LISTING_ALL_CERTS) {
            PR_fprintf(outputFD, "%s ", isSigningCert ? "*" : " ");
        }
        PR_fprintf(outputFD, "%s\n", name);

        if (LISTING_USER_SIGNING_CERTS) {
            int rv = SECFailure;
            if (rv) {
                CERTCertificate *issuerCert;
                issuerCert = CERT_FindCertIssuer(cert, PR_Now(),
                                                 certUsageObjectSigner);
                if (issuerCert) {
                    if (issuerCert->nickname && issuerCert->nickname[0]) {
                        PR_fprintf(outputFD, "    Issued by: %s\n",
                                   issuerCert->nickname);
                        rv = SECSuccess;
                    }
                    CERT_DestroyCertificate(issuerCert);
                }
            }
            if (rv && cert->issuerName && cert->issuerName[0]) {
                PR_fprintf(outputFD, "    Issued by: %s \n", cert->issuerName);
            }
            {
                char *expires;
                expires = DER_TimeChoiceDayToAscii(&cert->validity.notAfter);
                if (expires) {
                    PR_fprintf(outputFD, "    Expires: %s\n", expires);
                    PORT_Free(expires);
                }
            }

            rv = CERT_VerifyCertNow(cert->dbhandle, cert,
                                    PR_TRUE, certUsageObjectSigner, &pwdata);

            if (rv != SECSuccess) {
                rv = PORT_GetError();
                PR_fprintf(outputFD,
                           "    ++ Error ++ THIS CERTIFICATE IS NOT VALID (%s)\n",
                           secErrorString(rv));
            }
        }
    }

    return (SECSuccess);
}