Merge "Fix accessing freed memory in X509CertificateStore::Update()" into tizen
[platform/framework/native/appfw.git] / src / security / crypto / FSecCryptoDhKeyExchange.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 /**
17  * @file                FSecCryptoDhKeyExchange.cpp
18  * @brief               This file contains the implementation of Tizen::Security::Crypto::DhKeyExchange.
19  *
20  */
21 #include <unique_ptr.h>
22 #include <openssl/dh.h>
23 #include <openssl/bn.h>
24 #include <FBaseResult.h>
25 #include <FBaseErrors.h>
26 #include <FSecDhKeyParameters.h>
27 #include <FSecCryptoDhKeyExchange.h>
28 #include <FSecKeyPairGenerator.h>
29 #include <FBaseSysLog.h>
30
31 using namespace Tizen::Base;
32 using namespace Tizen::Security;
33
34
35 namespace Tizen { namespace Security { namespace Crypto
36 {
37 static const int _BITS_IN_BYTE = 8;
38
39 DhKeyExchange::DhKeyExchange(void)
40         : __pParamsP(null)
41         , __pParamsG(null)
42         , __pDhKeyExchangeImpl(null)
43 {
44
45 }
46
47 DhKeyExchange::~DhKeyExchange(void)
48 {
49         delete __pParamsP;
50         delete __pParamsG;
51 }
52
53 result
54 DhKeyExchange::Construct(const Tizen::Security::IKeyParameters& keyParameters)
55 {
56         result r = E_SUCCESS;
57         DhKeyParameters* pDhParams = null;
58
59         SysAssertf(__pParamsP == null && __pParamsG == null, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class");
60
61         pDhParams = const_cast< DhKeyParameters* >(dynamic_cast< const DhKeyParameters* >(&keyParameters));
62         SysTryReturn(NID_SEC_CRYPTO, pDhParams != null, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The dh key parameters value should be valid.");
63
64         //Retreive the value of the parameter 'p' from the instance
65         __pParamsP = pDhParams->GetParameterValueN(KEY_PARAMETER_DH_P);
66         SysTryReturn(NID_SEC_CRYPTO, __pParamsP != null, GetLastResult(), GetLastResult(), "[%s] Failed to get prime number", GetErrorMessage(GetLastResult()));
67
68         //Retreive the value of the parameter 'g' from the instance
69         __pParamsG = pDhParams->GetParameterValueN(KEY_PARAMETER_DH_G);
70         SysTryCatch(NID_SEC_CRYPTO, __pParamsG != null, r = GetLastResult(), GetLastResult(), "[%s] Failed to get generator number", GetErrorMessage(GetLastResult()));
71
72 CATCH:
73         if (IsFailed(r))
74         {
75                 delete __pParamsP;
76                 __pParamsP = null;
77         }
78         return r;
79 }
80
81 ByteBuffer*
82 DhKeyExchange::GenerateSecretN(Tizen::Security::IPrivateKey& privateKey, Tizen::Security::IPublicKey& publicKey)
83 {
84         result r = E_SUCCESS;
85         int outLen = 0;
86         int sizeParams = 0;
87         int sizePreMaster = 0;
88         DH* pDhStx = NULL;
89         BIGNUM* pDhPuKey = null;
90         std::unique_ptr<ByteBuffer> pOutput(null);
91
92         ClearLastResult();
93
94         SysAssertf(__pParamsP != null && __pParamsG != null, "Not yet constructed. Construct() should be called before use.");
95
96         std::unique_ptr<ByteBuffer> pPrivateComponent(privateKey.GetEncodedN());
97         SysTryReturn(NID_SEC_CRYPTO, pPrivateComponent != null, null, GetLastResult(), "[%s] Failed to fill private key buffer.", GetErrorMessage(GetLastResult()));
98
99         std::unique_ptr<ByteBuffer> pPublicComponent(publicKey.GetEncodedN());
100         SysTryReturn(NID_SEC_CRYPTO, pPublicComponent != null, null, GetLastResult(), "[%s] Failed to fill public key buffer.", GetErrorMessage(GetLastResult()));
101
102         sizeParams = pPrivateComponent->GetRemaining();
103         sizePreMaster = __pParamsP->GetRemaining();
104
105         std::unique_ptr<byte[]> pDhPreMasterSecret(new (std::nothrow) byte[sizePreMaster]);
106         SysTryReturn(NID_SEC_CRYPTO, pDhPreMasterSecret != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
107
108         pDhStx = DH_new();
109         SysTryCatch(NID_SEC_CRYPTO, pDhStx != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
110
111         pDhStx->p = BN_bin2bn(__pParamsP->GetPointer(), __pParamsP->GetRemaining(), NULL);
112         SysTryCatch(NID_SEC_CRYPTO, pDhStx->p != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
113
114         pDhStx->g = BN_bin2bn(__pParamsG->GetPointer(), __pParamsG->GetRemaining(), NULL);
115         SysTryCatch(NID_SEC_CRYPTO, pDhStx->g != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
116
117         pDhStx->length = sizeParams * _BITS_IN_BYTE;
118
119         pDhStx->priv_key = BN_bin2bn(pPrivateComponent->GetPointer(), pPrivateComponent->GetRemaining(), NULL);
120         SysTryCatch(NID_SEC_CRYPTO, pDhStx->priv_key != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
121
122         pDhPuKey = BN_bin2bn(pPublicComponent->GetPointer(), pPublicComponent->GetRemaining(), NULL);
123         SysTryCatch(NID_SEC_CRYPTO, pDhPuKey != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
124
125         outLen = DH_compute_key(pDhPreMasterSecret.get(), pDhPuKey, pDhStx);
126         SysTryCatch(NID_SEC_CRYPTO, pDhPreMasterSecret != null && outLen != -1, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
127
128         pOutput = std::unique_ptr<ByteBuffer>(new (std::nothrow) ByteBuffer());
129         SysTryCatch(NID_SEC_CRYPTO, pOutput != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
130
131         r = pOutput->Construct(outLen);
132         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to allocate memory.");
133
134         r = pOutput->SetArray(pDhPreMasterSecret.get(), 0, outLen);
135         SysTryCatch(NID_SEC_CRYPTO, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] An unexpected system error occurred.");
136
137         pOutput->Flip();
138
139 CATCH:
140
141         if (IsFailed(r))
142         {
143                 pOutput.reset(null);
144         }
145
146         if (pDhStx != null)
147         {
148                 DH_free(pDhStx);
149         }
150
151         return pOutput.release();
152 }
153
154 } } } //Tizen::Security::Crypto