Exemple #1
0
SECStatus
SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert,
                                    const CERTCertificateList *certChainOpt,
                                    SECKEYPrivateKey *key, SSL3KEAType kea)
{
    sslSocket *ss;
    SECKEYPublicKey *pubKey = NULL;
    ssl3KeyPair *keyPair = NULL;
    SECStatus rv = SECFailure;

    ss = ssl_FindSocket(fd);
    if (!ss) {
	return SECFailure;
    }

    /* Both key and cert must have a value or be NULL */
    /* Passing a value of NULL will turn off key exchange algorithms that were
     * previously turned on */
    if (!cert != !key) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    /* make sure the key exchange is recognized */
    if ((kea >= kt_kea_size) || (kea < kt_null)) {
	PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
	return SECFailure;
    }

    if (kea != NSS_FindCertKEAType(cert)) {
    	PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH);
	return SECFailure;
    }

    if (cert) {
    	/* get the size of the cert's public key, and remember it */
	pubKey = CERT_ExtractPublicKey(cert);
	if (!pubKey) 
            return SECFailure;
    }

    if (key) {
	SECKEYPrivateKey * keyCopy	= NULL;
	CK_MECHANISM_TYPE  keyMech	= CKM_INVALID_MECHANISM;

	if (key->pkcs11Slot) {
	    PK11SlotInfo * bestSlot;
	    bestSlot = PK11_ReferenceSlot(key->pkcs11Slot);
	    if (bestSlot) {
		keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
		PK11_FreeSlot(bestSlot);
	    }
	}
	if (keyCopy == NULL)
	    keyMech = PK11_MapSignKeyType(key->keyType);
	if (keyMech != CKM_INVALID_MECHANISM) {
	    PK11SlotInfo * bestSlot;
	    /* XXX Maybe should be bestSlotMultiple? */
	    bestSlot = PK11_GetBestSlot(keyMech, NULL /* wincx */);
	    if (bestSlot) {
		keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
		PK11_FreeSlot(bestSlot);
	    }
	}
	if (keyCopy == NULL)
	    keyCopy = SECKEY_CopyPrivateKey(key);
	if (keyCopy == NULL)
	    goto loser;
        keyPair = ssl3_NewKeyPair(keyCopy, pubKey);
        if (keyPair == NULL) {
            SECKEY_DestroyPrivateKey(keyCopy);
            goto loser;
        }
	pubKey = NULL; /* adopted by serverKeyPair */
    }
    if (ssl_ConfigSecureServer(ss, cert, certChainOpt,
                               keyPair, kea) == SECFailure) {
        goto loser;
    }

    /* Only do this once because it's global. */
    if (PR_SUCCESS == PR_CallOnceWithArg(&setupServerCAListOnce, 
                                         &serverCAListSetup,
                                         (void *)(ss->dbHandle))) {
        rv = SECSuccess;
    }

loser:
    if (keyPair) {
        ssl3_FreeKeyPair(keyPair);
    }
    if (pubKey) {
	SECKEY_DestroyPublicKey(pubKey); 
	pubKey = NULL;
    }
    return rv;
}
SECStatus
SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert,
                                    const CERTCertificateList *certChainOpt,
                                    SECKEYPrivateKey *key, SSL3KEAType kea)
{
    sslSocket *ss;
    SECKEYPublicKey *pubKey = NULL;
    ssl3KeyPair *keyPair = NULL;
    SECStatus rv = SECFailure;

    ss = ssl_FindSocket(fd);
    if (!ss) {
	return SECFailure;
    }

    
    if (!cert != !key) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    
    if ((kea >= kt_kea_size) || (kea < kt_null)) {
	PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
	return SECFailure;
    }

    if (kea != NSS_FindCertKEAType(cert)) {
    	PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH);
	return SECFailure;
    }

    if (cert) {
    	
	pubKey = CERT_ExtractPublicKey(cert);
	if (!pubKey) 
            return SECFailure;
    }

    if (key) {
	SECKEYPrivateKey * keyCopy	= NULL;
	CK_MECHANISM_TYPE  keyMech	= CKM_INVALID_MECHANISM;

	if (key->pkcs11Slot) {
	    PK11SlotInfo * bestSlot;
	    bestSlot = PK11_ReferenceSlot(key->pkcs11Slot);
	    if (bestSlot) {
		keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
		PK11_FreeSlot(bestSlot);
	    }
	}
	if (keyCopy == NULL)
	    keyMech = PK11_MapSignKeyType(key->keyType);
	if (keyMech != CKM_INVALID_MECHANISM) {
	    PK11SlotInfo * bestSlot;
	    
	    bestSlot = PK11_GetBestSlot(keyMech, NULL );
	    if (bestSlot) {
		keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
		PK11_FreeSlot(bestSlot);
	    }
	}
	if (keyCopy == NULL)
	    keyCopy = SECKEY_CopyPrivateKey(key);
	if (keyCopy == NULL)
	    goto loser;
        keyPair = ssl3_NewKeyPair(keyCopy, pubKey);
        if (keyPair == NULL) {
            SECKEY_DestroyPrivateKey(keyCopy);
            goto loser;
        }
	pubKey = NULL; 
    }
    if (ssl_ConfigSecureServer(ss, cert, certChainOpt,
                               keyPair, kea) == SECFailure) {
        goto loser;
    }

    
    if (PR_SUCCESS == PR_CallOnceWithArg(&setupServerCAListOnce, 
                                         &serverCAListSetup,
                                         (void *)(ss->dbHandle))) {
        rv = SECSuccess;
    }

loser:
    if (keyPair) {
        ssl3_FreeKeyPair(keyPair);
    }
    if (pubKey) {
	SECKEY_DestroyPublicKey(pubKey); 
	pubKey = NULL;
    }
    return rv;
}