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 |