| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Key Derivation that doesn't use PKCS11 | 2 * Key Derivation that doesn't use PKCS11 |
| 3 * | 3 * |
| 4 * ***** BEGIN LICENSE BLOCK ***** | 4 * ***** BEGIN LICENSE BLOCK ***** |
| 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
| 6 * | 6 * |
| 7 * The contents of this file are subject to the Mozilla Public License Version | 7 * The contents of this file are subject to the Mozilla Public License Version |
| 8 * 1.1 (the "License"); you may not use this file except in compliance with | 8 * 1.1 (the "License"); you may not use this file except in compliance with |
| 9 * the License. You may obtain a copy of the License at | 9 * the License. You may obtain a copy of the License at |
| 10 * http://www.mozilla.org/MPL/ | 10 * http://www.mozilla.org/MPL/ |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 * in which case the provisions of the GPL or the LGPL are applicable instead | 29 * in which case the provisions of the GPL or the LGPL are applicable instead |
| 30 * of those above. If you wish to allow use of your version of this file only | 30 * of those above. If you wish to allow use of your version of this file only |
| 31 * under the terms of either the GPL or the LGPL, and not to allow others to | 31 * under the terms of either the GPL or the LGPL, and not to allow others to |
| 32 * use your version of this file under the terms of the MPL, indicate your | 32 * use your version of this file under the terms of the MPL, indicate your |
| 33 * decision by deleting the provisions above and replace them with the notice | 33 * decision by deleting the provisions above and replace them with the notice |
| 34 * and other provisions required by the GPL or the LGPL. If you do not delete | 34 * and other provisions required by the GPL or the LGPL. If you do not delete |
| 35 * the provisions above, a recipient may use your version of this file under | 35 * the provisions above, a recipient may use your version of this file under |
| 36 * the terms of any one of the MPL, the GPL or the LGPL. | 36 * the terms of any one of the MPL, the GPL or the LGPL. |
| 37 * | 37 * |
| 38 * ***** END LICENSE BLOCK ***** */ | 38 * ***** END LICENSE BLOCK ***** */ |
| 39 /* $Id: derive.c,v 1.12 2008/06/06 01:16:31 wtc%google.com Exp $ */ | 39 /* $Id: derive.c,v 1.13 2011/03/22 22:15:22 alexei.volkov.bugs%sun.com Exp $ */ |
| 40 | 40 |
| 41 #include "ssl.h" /* prereq to sslimpl.h */ | 41 #include "ssl.h" /* prereq to sslimpl.h */ |
| 42 #include "certt.h" /* prereq to sslimpl.h */ | 42 #include "certt.h" /* prereq to sslimpl.h */ |
| 43 #include "keythi.h" /* prereq to sslimpl.h */ | 43 #include "keythi.h" /* prereq to sslimpl.h */ |
| 44 #include "sslimpl.h" | 44 #include "sslimpl.h" |
| 45 #include "blapi.h" | 45 #include "blapi.h" |
| 46 | 46 |
| 47 #include "keyhi.h" | 47 #include "keyhi.h" |
| 48 #include "pk11func.h" | 48 #include "pk11func.h" |
| 49 #include "secasn1.h" | 49 #include "secasn1.h" |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 SECItem param; | 597 SECItem param; |
| 598 CK_VERSION version; | 598 CK_VERSION version; |
| 599 CK_MECHANISM_TYPE mechanism_array[2]; | 599 CK_MECHANISM_TYPE mechanism_array[2]; |
| 600 SECItem enc_pms = {siBuffer, NULL, 0}; | 600 SECItem enc_pms = {siBuffer, NULL, 0}; |
| 601 PRBool isTLS = PR_FALSE; | 601 PRBool isTLS = PR_FALSE; |
| 602 SSLCipherSuiteInfo csdef; | 602 SSLCipherSuiteInfo csdef; |
| 603 PRBool testrsa = PR_FALSE; | 603 PRBool testrsa = PR_FALSE; |
| 604 PRBool testrsa_export = PR_FALSE; | 604 PRBool testrsa_export = PR_FALSE; |
| 605 PRBool testecdh = PR_FALSE; | 605 PRBool testecdh = PR_FALSE; |
| 606 PRBool testecdhe = PR_FALSE; | 606 PRBool testecdhe = PR_FALSE; |
| 607 #ifdef NSS_ENABLE_ECC |
| 608 SECKEYECParams ecParams = { siBuffer, NULL, 0 }; |
| 609 #endif |
| 607 | 610 |
| 608 if (!cert || !srvPrivkey || !ciphersuites || !pcanbypass) { | 611 if (!cert || !srvPrivkey || !ciphersuites || !pcanbypass) { |
| 609 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 612 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
| 610 return SECFailure; | 613 return SECFailure; |
| 611 } | 614 } |
| 612 | 615 |
| 613 srvPubkey = CERT_ExtractPublicKey(cert); | 616 srvPubkey = CERT_ExtractPublicKey(cert); |
| 614 if (!srvPubkey) | 617 if (!srvPubkey) |
| 615 return SECFailure; | 618 return SECFailure; |
| 616 | 619 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 696 version.minor = 0 /*LSB(clientHelloVersion)*/; | 699 version.minor = 0 /*LSB(clientHelloVersion)*/; |
| 697 param.data = (unsigned char *)&version; | 700 param.data = (unsigned char *)&version; |
| 698 param.len = sizeof version; | 701 param.len = sizeof version; |
| 699 pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, ¶m, 0, pwAr
g); | 702 pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, ¶m, 0, pwAr
g); |
| 700 PK11_FreeSlot(slot); | 703 PK11_FreeSlot(slot); |
| 701 if (!pms) | 704 if (!pms) |
| 702 break; | 705 break; |
| 703 /* now wrap it */ | 706 /* now wrap it */ |
| 704 enc_pms.len = SECKEY_PublicKeyStrength(srvPubkey); | 707 enc_pms.len = SECKEY_PublicKeyStrength(srvPubkey); |
| 705 enc_pms.data = (unsigned char*)PORT_Alloc(enc_pms.len); | 708 enc_pms.data = (unsigned char*)PORT_Alloc(enc_pms.len); |
| 709 if (enc_pms.data == NULL) { |
| 710 PORT_SetError(PR_OUT_OF_MEMORY_ERROR); |
| 711 break; |
| 712 } |
| 706 irv = PK11_PubWrapSymKey(CKM_RSA_PKCS, srvPubkey, pms, &enc_pms); | 713 irv = PK11_PubWrapSymKey(CKM_RSA_PKCS, srvPubkey, pms, &enc_pms); |
| 707 if (irv != SECSuccess) | 714 if (irv != SECSuccess) |
| 708 break; | 715 break; |
| 709 PK11_FreeSymKey(pms); | 716 PK11_FreeSymKey(pms); |
| 717 pms = NULL; |
| 710 /* now do the server side--check the triple bypass first */ | 718 /* now do the server side--check the triple bypass first */ |
| 711 rv = PK11_PrivDecryptPKCS1(srvPrivkey, rsaPmsBuf, &outLen, | 719 rv = PK11_PrivDecryptPKCS1(srvPrivkey, rsaPmsBuf, &outLen, |
| 712 sizeof rsaPmsBuf, | 720 sizeof rsaPmsBuf, |
| 713 (unsigned char *)enc_pms.data, | 721 (unsigned char *)enc_pms.data, |
| 714 enc_pms.len); | 722 enc_pms.len); |
| 715 /* if decrypt worked we're done with the RSA test */ | 723 /* if decrypt worked we're done with the RSA test */ |
| 716 if (rv == SECSuccess) { | 724 if (rv == SECSuccess) { |
| 717 *pcanbypass = PR_TRUE; | 725 *pcanbypass = PR_TRUE; |
| 718 break; | 726 break; |
| 719 } | 727 } |
| 720 /* check for fallback to double bypass */ | 728 /* check for fallback to double bypass */ |
| 721 target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE | 729 target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE |
| 722 : CKM_SSL3_MASTER_KEY_DERIVE; | 730 : CKM_SSL3_MASTER_KEY_DERIVE; |
| 723 pms = PK11_PubUnwrapSymKey(srvPrivkey, &enc_pms, | 731 pms = PK11_PubUnwrapSymKey(srvPrivkey, &enc_pms, |
| 724 target, CKA_DERIVE, 0); | 732 target, CKA_DERIVE, 0); |
| 725 rv = ssl_canExtractMS(pms, isTLS, PR_FALSE, pcanbypass); | 733 rv = ssl_canExtractMS(pms, isTLS, PR_FALSE, pcanbypass); |
| 726 if (rv == SECSuccess && *pcanbypass == PR_FALSE) | 734 if (rv == SECSuccess && *pcanbypass == PR_FALSE) |
| 727 goto done; | 735 goto done; |
| 728 break; | 736 break; |
| 729 } | 737 } |
| 738 |
| 739 /* Check for NULL to avoid double free. |
| 740 * SECItem_FreeItem sets data NULL in secitem.c#265 |
| 741 */ |
| 742 if (enc_pms.data != NULL) { |
| 743 SECITEM_FreeItem(&enc_pms, PR_FALSE); |
| 744 } |
| 730 #ifdef NSS_ENABLE_ECC | 745 #ifdef NSS_ENABLE_ECC |
| 731 for (; (privKeytype == ecKey && ( testecdh || testecdhe)) || | 746 for (; (privKeytype == ecKey && ( testecdh || testecdhe)) || |
| 732 (privKeytype == rsaKey && testecdhe); ) { | 747 (privKeytype == rsaKey && testecdhe); ) { |
| 733 CK_MECHANISM_TYPE target; | 748 CK_MECHANISM_TYPE target; |
| 734 SECKEYPublicKey *keapub = NULL; | 749 SECKEYPublicKey *keapub = NULL; |
| 735 SECKEYPrivateKey *keapriv; | 750 SECKEYPrivateKey *keapriv; |
| 736 SECKEYPublicKey *cpub = NULL; /* client's ephemeral ECDH keys */ | 751 SECKEYPublicKey *cpub = NULL; /* client's ephemeral ECDH keys */ |
| 737 SECKEYPrivateKey *cpriv = NULL; | 752 SECKEYPrivateKey *cpriv = NULL; |
| 738 » SECKEYECParams ecParams = { siBuffer, NULL, 0 }, | 753 » SECKEYECParams *pecParams = NULL; |
| 739 » » » *pecParams; | |
| 740 | 754 |
| 741 if (privKeytype == ecKey && testecdhe) { | 755 if (privKeytype == ecKey && testecdhe) { |
| 742 /* TLS_ECDHE_ECDSA */ | 756 /* TLS_ECDHE_ECDSA */ |
| 743 pecParams = &srvPubkey->u.ec.DEREncodedParams; | 757 pecParams = &srvPubkey->u.ec.DEREncodedParams; |
| 744 } else if (privKeytype == rsaKey && testecdhe) { | 758 } else if (privKeytype == rsaKey && testecdhe) { |
| 745 /* TLS_ECDHE_RSA */ | 759 /* TLS_ECDHE_RSA */ |
| 746 ECName ec_curve; | 760 ECName ec_curve; |
| 747 int serverKeyStrengthInBits; | 761 int serverKeyStrengthInBits; |
| 748 int signatureKeyStrength; | 762 int signatureKeyStrength; |
| 749 int requiredECCbits; | 763 int requiredECCbits; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 814 pms = PK11_PubDeriveWithKDF(keapriv, cpub, PR_FALSE, NULL, NULL, | 828 pms = PK11_PubDeriveWithKDF(keapriv, cpub, PR_FALSE, NULL, NULL, |
| 815 CKM_ECDH1_DERIVE, | 829 CKM_ECDH1_DERIVE, |
| 816 target, | 830 target, |
| 817 CKA_DERIVE, 0, CKD_NULL, NULL, NULL); | 831 CKA_DERIVE, 0, CKD_NULL, NULL, NULL); |
| 818 rv = ssl_canExtractMS(pms, isTLS, PR_TRUE, pcanbypass); | 832 rv = ssl_canExtractMS(pms, isTLS, PR_TRUE, pcanbypass); |
| 819 SECKEY_DestroyPrivateKey(cpriv); | 833 SECKEY_DestroyPrivateKey(cpriv); |
| 820 SECKEY_DestroyPublicKey(cpub); | 834 SECKEY_DestroyPublicKey(cpub); |
| 821 if (testecdhe) { | 835 if (testecdhe) { |
| 822 SECKEY_DestroyPrivateKey(keapriv); | 836 SECKEY_DestroyPrivateKey(keapriv); |
| 823 SECKEY_DestroyPublicKey(keapub); | 837 SECKEY_DestroyPublicKey(keapub); |
| 824 if (privKeytype == rsaKey) | |
| 825 PORT_Free(ecParams.data); | |
| 826 } | 838 } |
| 827 if (rv == SECSuccess && *pcanbypass == PR_FALSE) | 839 if (rv == SECSuccess && *pcanbypass == PR_FALSE) |
| 828 goto done; | 840 goto done; |
| 829 break; | 841 break; |
| 830 } | 842 } |
| 843 /* Check for NULL to avoid double free. */ |
| 844 if (ecParams.data != NULL) { |
| 845 PORT_Free(ecParams.data); |
| 846 ecParams.data = NULL; |
| 847 } |
| 831 #endif /* NSS_ENABLE_ECC */ | 848 #endif /* NSS_ENABLE_ECC */ |
| 832 if (pms) | 849 if (pms) |
| 833 PK11_FreeSymKey(pms); | 850 PK11_FreeSymKey(pms); |
| 834 } | 851 } |
| 835 | 852 |
| 836 /* *pcanbypass has been set */ | 853 /* *pcanbypass has been set */ |
| 837 rv = SECSuccess; | 854 rv = SECSuccess; |
| 838 | 855 |
| 839 done: | 856 done: |
| 840 if (pms) | 857 if (pms) |
| 841 PK11_FreeSymKey(pms); | 858 PK11_FreeSymKey(pms); |
| 842 | 859 |
| 843 SECITEM_FreeItem(&enc_pms, PR_FALSE); | 860 /* Check for NULL to avoid double free. |
| 861 * SECItem_FreeItem sets data NULL in secitem.c#265 |
| 862 */ |
| 863 if (enc_pms.data != NULL) { |
| 864 » SECITEM_FreeItem(&enc_pms, PR_FALSE); |
| 865 } |
| 866 #ifdef NSS_ENABLE_ECC |
| 867 if (ecParams.data != NULL) { |
| 868 PORT_Free(ecParams.data); |
| 869 ecParams.data = NULL; |
| 870 } |
| 871 #endif /* NSS_ENABLE_ECC */ |
| 844 | 872 |
| 845 if (srvPubkey) { | 873 if (srvPubkey) { |
| 846 SECKEY_DestroyPublicKey(srvPubkey); | 874 SECKEY_DestroyPublicKey(srvPubkey); |
| 847 srvPubkey = NULL; | 875 srvPubkey = NULL; |
| 848 } | 876 } |
| 849 | 877 |
| 850 | 878 |
| 851 return rv; | 879 return rv; |
| 852 } | 880 } |
| 853 | 881 |
| OLD | NEW |