Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 
 

579 рядки
17 KiB

  1. /* Written by Nils Larsch for the OpenSSL project. */
  2. /* ====================================================================
  3. * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in
  14. * the documentation and/or other materials provided with the
  15. * distribution.
  16. *
  17. * 3. All advertising materials mentioning features or use of this
  18. * software must display the following acknowledgment:
  19. * "This product includes software developed by the OpenSSL Project
  20. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  21. *
  22. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  23. * endorse or promote products derived from this software without
  24. * prior written permission. For written permission, please contact
  25. * licensing@OpenSSL.org.
  26. *
  27. * 5. Products derived from this software may not be called "OpenSSL"
  28. * nor may "OpenSSL" appear in their names without prior written
  29. * permission of the OpenSSL Project.
  30. *
  31. * 6. Redistributions of any form whatsoever must retain the following
  32. * acknowledgment:
  33. * "This product includes software developed by the OpenSSL Project
  34. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  35. *
  36. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  37. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  38. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  39. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  42. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  44. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  45. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  46. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  47. * OF THE POSSIBILITY OF SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This product includes cryptographic software written by Eric Young
  51. * (eay@cryptsoft.com). This product includes software written by Tim
  52. * Hudson (tjh@cryptsoft.com). */
  53. #include <openssl/ec.h>
  54. #include <string.h>
  55. #include <openssl/asn1.h>
  56. #include <openssl/asn1t.h>
  57. #include <openssl/bn.h>
  58. #include <openssl/err.h>
  59. #include <openssl/mem.h>
  60. #include <openssl/obj.h>
  61. #include "internal.h"
  62. typedef struct x9_62_fieldid_st {
  63. ASN1_OBJECT *fieldType;
  64. union {
  65. char *ptr;
  66. /* NID_X9_62_prime_field */
  67. ASN1_INTEGER *prime;
  68. /* anything else */
  69. ASN1_TYPE *other;
  70. } p;
  71. } X9_62_FIELDID;
  72. ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
  73. ASN1_ADB(X9_62_FIELDID) = {
  74. ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
  75. } ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
  76. ASN1_SEQUENCE(X9_62_FIELDID) = {
  77. ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
  78. ASN1_ADB_OBJECT(X9_62_FIELDID)
  79. } ASN1_SEQUENCE_END(X9_62_FIELDID);
  80. typedef struct x9_62_curve_st {
  81. ASN1_OCTET_STRING *a;
  82. ASN1_OCTET_STRING *b;
  83. ASN1_BIT_STRING *seed;
  84. } X9_62_CURVE;
  85. ASN1_SEQUENCE(X9_62_CURVE) = {
  86. ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
  87. ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
  88. ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
  89. } ASN1_SEQUENCE_END(X9_62_CURVE);
  90. typedef struct ec_parameters_st {
  91. long version;
  92. X9_62_FIELDID *fieldID;
  93. X9_62_CURVE *curve;
  94. ASN1_OCTET_STRING *base;
  95. ASN1_INTEGER *order;
  96. ASN1_INTEGER *cofactor;
  97. } ECPARAMETERS;
  98. DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS);
  99. ASN1_SEQUENCE(ECPARAMETERS) = {
  100. ASN1_SIMPLE(ECPARAMETERS, version, LONG),
  101. ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
  102. ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
  103. ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
  104. ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
  105. ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
  106. } ASN1_SEQUENCE_END(ECPARAMETERS);
  107. IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS);
  108. typedef struct ecpk_parameters_st {
  109. int type;
  110. union {
  111. ASN1_OBJECT *named_curve;
  112. ECPARAMETERS *parameters;
  113. } value;
  114. } ECPKPARAMETERS;
  115. /* SEC1 ECPrivateKey */
  116. typedef struct ec_privatekey_st {
  117. long version;
  118. ASN1_OCTET_STRING *privateKey;
  119. ECPKPARAMETERS *parameters;
  120. ASN1_BIT_STRING *publicKey;
  121. } EC_PRIVATEKEY;
  122. DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS);
  123. DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS);
  124. ASN1_CHOICE(ECPKPARAMETERS) = {
  125. ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
  126. ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
  127. } ASN1_CHOICE_END(ECPKPARAMETERS);
  128. IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS);
  129. DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY);
  130. DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY);
  131. ASN1_SEQUENCE(EC_PRIVATEKEY) = {
  132. ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
  133. ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
  134. ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
  135. ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1),
  136. } ASN1_SEQUENCE_END(EC_PRIVATEKEY);
  137. IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY);
  138. ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
  139. ECPKPARAMETERS *params) {
  140. int ok = 0, nid;
  141. ECPKPARAMETERS *ret = params;
  142. if (ret == NULL) {
  143. ret = ECPKPARAMETERS_new();
  144. if (ret == NULL) {
  145. OPENSSL_PUT_ERROR(EC, ec_asn1_group2pkparameters, ERR_R_MALLOC_FAILURE);
  146. return NULL;
  147. }
  148. } else {
  149. ASN1_OBJECT_free(ret->value.named_curve);
  150. }
  151. /* use the ASN.1 OID to describe the the elliptic curve parameters. */
  152. nid = EC_GROUP_get_curve_name(group);
  153. if (nid) {
  154. ret->type = 0;
  155. ret->value.named_curve = (ASN1_OBJECT*) OBJ_nid2obj(nid);
  156. ok = ret->value.named_curve != NULL;
  157. }
  158. if (!ok) {
  159. ECPKPARAMETERS_free(ret);
  160. return NULL;
  161. }
  162. return ret;
  163. }
  164. EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) {
  165. EC_GROUP *ret = NULL;
  166. int nid = NID_undef;
  167. if (params == NULL) {
  168. OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group, EC_R_MISSING_PARAMETERS);
  169. return NULL;
  170. }
  171. if (params->type == 0) {
  172. nid = OBJ_obj2nid(params->value.named_curve);
  173. } else if (params->type == 1) {
  174. /* We don't support arbitary curves so we attempt to recognise it from the
  175. * group order. */
  176. const ECPARAMETERS *ecparams = params->value.parameters;
  177. unsigned i;
  178. const struct built_in_curve *curve;
  179. for (i = 0; OPENSSL_built_in_curves[i].nid != NID_undef; i++) {
  180. curve = &OPENSSL_built_in_curves[i];
  181. const unsigned param_len = curve->data->param_len;
  182. if (ecparams->order->length == param_len &&
  183. memcmp(ecparams->order->data, &curve->data->data[param_len * 5],
  184. param_len) == 0) {
  185. nid = curve->nid;
  186. break;
  187. }
  188. }
  189. }
  190. if (nid == NID_undef) {
  191. OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group, EC_R_NON_NAMED_CURVE);
  192. return NULL;
  193. }
  194. ret = EC_GROUP_new_by_curve_name(nid);
  195. if (ret == NULL) {
  196. OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group,
  197. EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
  198. return NULL;
  199. }
  200. return ret;
  201. }
  202. static EC_GROUP *d2i_ECPKParameters(EC_GROUP **groupp, const uint8_t **inp,
  203. long len) {
  204. EC_GROUP *group = NULL;
  205. ECPKPARAMETERS *params = NULL;
  206. params = d2i_ECPKPARAMETERS(NULL, inp, len);
  207. if (params == NULL) {
  208. OPENSSL_PUT_ERROR(EC, d2i_ECPKParameters, EC_R_D2I_ECPKPARAMETERS_FAILURE);
  209. ECPKPARAMETERS_free(params);
  210. return NULL;
  211. }
  212. group = ec_asn1_pkparameters2group(params);
  213. if (group == NULL) {
  214. OPENSSL_PUT_ERROR(EC, d2i_ECPKParameters, EC_R_PKPARAMETERS2GROUP_FAILURE);
  215. ECPKPARAMETERS_free(params);
  216. return NULL;
  217. }
  218. if (groupp) {
  219. EC_GROUP_free(*groupp);
  220. *groupp = group;
  221. }
  222. ECPKPARAMETERS_free(params);
  223. return group;
  224. }
  225. static int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp) {
  226. int ret = 0;
  227. ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(group, NULL);
  228. if (tmp == NULL) {
  229. OPENSSL_PUT_ERROR(EC, i2d_ECPKParameters, EC_R_GROUP2PKPARAMETERS_FAILURE);
  230. return 0;
  231. }
  232. ret = i2d_ECPKPARAMETERS(tmp, outp);
  233. if (ret == 0) {
  234. OPENSSL_PUT_ERROR(EC, i2d_ECPKParameters, EC_R_I2D_ECPKPARAMETERS_FAILURE);
  235. ECPKPARAMETERS_free(tmp);
  236. return 0;
  237. }
  238. ECPKPARAMETERS_free(tmp);
  239. return ret;
  240. }
  241. EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
  242. int ok = 0;
  243. EC_KEY *ret = NULL;
  244. EC_PRIVATEKEY *priv_key = NULL;
  245. priv_key = d2i_EC_PRIVATEKEY(NULL, in, len);
  246. if (priv_key == NULL) {
  247. OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
  248. return NULL;
  249. }
  250. if (a == NULL || *a == NULL) {
  251. ret = EC_KEY_new();
  252. if (ret == NULL) {
  253. OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_MALLOC_FAILURE);
  254. goto err;
  255. }
  256. } else {
  257. ret = *a;
  258. }
  259. if (priv_key->parameters) {
  260. EC_GROUP_free(ret->group);
  261. ret->group = ec_asn1_pkparameters2group(priv_key->parameters);
  262. }
  263. if (ret->group == NULL) {
  264. OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
  265. goto err;
  266. }
  267. ret->version = priv_key->version;
  268. if (priv_key->privateKey) {
  269. ret->priv_key =
  270. BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey),
  271. M_ASN1_STRING_length(priv_key->privateKey), ret->priv_key);
  272. if (ret->priv_key == NULL) {
  273. OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_BN_LIB);
  274. goto err;
  275. }
  276. } else {
  277. OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, EC_R_MISSING_PRIVATE_KEY);
  278. goto err;
  279. }
  280. EC_POINT_free(ret->pub_key);
  281. ret->pub_key = EC_POINT_new(ret->group);
  282. if (ret->pub_key == NULL) {
  283. OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
  284. goto err;
  285. }
  286. if (priv_key->publicKey) {
  287. const uint8_t *pub_oct;
  288. int pub_oct_len;
  289. pub_oct = M_ASN1_STRING_data(priv_key->publicKey);
  290. pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
  291. /* The first byte (the point conversion form) must be present. */
  292. if (pub_oct_len <= 0) {
  293. OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, EC_R_BUFFER_TOO_SMALL);
  294. goto err;
  295. }
  296. /* Save the point conversion form. */
  297. ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
  298. if (!EC_POINT_oct2point(ret->group, ret->pub_key, pub_oct, pub_oct_len,
  299. NULL)) {
  300. OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
  301. goto err;
  302. }
  303. } else {
  304. if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, NULL, NULL,
  305. NULL)) {
  306. OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
  307. goto err;
  308. }
  309. /* Remember the original private-key-only encoding. */
  310. ret->enc_flag |= EC_PKEY_NO_PUBKEY;
  311. }
  312. if (a) {
  313. *a = ret;
  314. }
  315. ok = 1;
  316. err:
  317. if (!ok) {
  318. if (a == NULL || *a != ret) {
  319. EC_KEY_free(ret);
  320. }
  321. ret = NULL;
  322. }
  323. EC_PRIVATEKEY_free(priv_key);
  324. return ret;
  325. }
  326. int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
  327. int ret = 0, ok = 0;
  328. uint8_t *buffer = NULL;
  329. size_t buf_len = 0, tmp_len;
  330. EC_PRIVATEKEY *priv_key = NULL;
  331. if (key == NULL || key->group == NULL || key->priv_key == NULL) {
  332. OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_PASSED_NULL_PARAMETER);
  333. goto err;
  334. }
  335. priv_key = EC_PRIVATEKEY_new();
  336. if (priv_key == NULL) {
  337. OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
  338. goto err;
  339. }
  340. priv_key->version = key->version;
  341. buf_len = BN_num_bytes(&key->group->order);
  342. buffer = OPENSSL_malloc(buf_len);
  343. if (buffer == NULL) {
  344. OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
  345. goto err;
  346. }
  347. if (!BN_bn2bin_padded(buffer, buf_len, key->priv_key)) {
  348. OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_BN_LIB);
  349. goto err;
  350. }
  351. if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
  352. OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_ASN1_LIB);
  353. goto err;
  354. }
  355. /* TODO(fork): replace this flexibility with key sensible default? */
  356. if (!(key->enc_flag & EC_PKEY_NO_PARAMETERS)) {
  357. if ((priv_key->parameters = ec_asn1_group2pkparameters(
  358. key->group, priv_key->parameters)) == NULL) {
  359. OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
  360. goto err;
  361. }
  362. }
  363. /* TODO(fork): replace this flexibility with key sensible default? */
  364. if (!(key->enc_flag & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) {
  365. priv_key->publicKey = M_ASN1_BIT_STRING_new();
  366. if (priv_key->publicKey == NULL) {
  367. OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
  368. goto err;
  369. }
  370. tmp_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL,
  371. 0, NULL);
  372. if (tmp_len > buf_len) {
  373. uint8_t *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
  374. if (!tmp_buffer) {
  375. OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
  376. goto err;
  377. }
  378. buffer = tmp_buffer;
  379. buf_len = tmp_len;
  380. }
  381. if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, buffer,
  382. buf_len, NULL)) {
  383. OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
  384. goto err;
  385. }
  386. priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
  387. priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
  388. if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) {
  389. OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_ASN1_LIB);
  390. goto err;
  391. }
  392. }
  393. ret = i2d_EC_PRIVATEKEY(priv_key, outp);
  394. if (ret == 0) {
  395. OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
  396. goto err;
  397. }
  398. ok = 1;
  399. err:
  400. OPENSSL_free(buffer);
  401. EC_PRIVATEKEY_free(priv_key);
  402. return (ok ? ret : 0);
  403. }
  404. int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) {
  405. if (key == NULL) {
  406. OPENSSL_PUT_ERROR(EC, i2d_ECParameters, ERR_R_PASSED_NULL_PARAMETER);
  407. return 0;
  408. }
  409. return i2d_ECPKParameters(key->group, outp);
  410. }
  411. EC_KEY *d2i_ECParameters(EC_KEY **key, const uint8_t **inp, long len) {
  412. EC_KEY *ret;
  413. if (inp == NULL || *inp == NULL) {
  414. OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_PASSED_NULL_PARAMETER);
  415. return NULL;
  416. }
  417. if (key == NULL || *key == NULL) {
  418. ret = EC_KEY_new();
  419. if (ret == NULL) {
  420. OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_MALLOC_FAILURE);
  421. return NULL;
  422. }
  423. } else {
  424. ret = *key;
  425. }
  426. if (!d2i_ECPKParameters(&ret->group, inp, len)) {
  427. OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_EC_LIB);
  428. if (key == NULL || *key == NULL) {
  429. EC_KEY_free(ret);
  430. }
  431. return NULL;
  432. }
  433. if (key) {
  434. *key = ret;
  435. }
  436. return ret;
  437. }
  438. EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) {
  439. EC_KEY *ret = NULL;
  440. if (keyp == NULL || *keyp == NULL || (*keyp)->group == NULL) {
  441. OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_PASSED_NULL_PARAMETER);
  442. return 0;
  443. }
  444. ret = *keyp;
  445. if (ret->pub_key == NULL &&
  446. (ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
  447. OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_MALLOC_FAILURE);
  448. return 0;
  449. }
  450. if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) {
  451. OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_EC_LIB);
  452. return 0;
  453. }
  454. /* save the point conversion form */
  455. ret->conv_form = (point_conversion_form_t)(*inp[0] & ~0x01);
  456. *inp += len;
  457. return ret;
  458. }
  459. int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) {
  460. size_t buf_len = 0;
  461. int new_buffer = 0;
  462. if (key == NULL) {
  463. OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_PASSED_NULL_PARAMETER);
  464. return 0;
  465. }
  466. buf_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL,
  467. 0, NULL);
  468. if (outp == NULL || buf_len == 0) {
  469. /* out == NULL => just return the length of the octet string */
  470. return buf_len;
  471. }
  472. if (*outp == NULL) {
  473. *outp = OPENSSL_malloc(buf_len);
  474. if (*outp == NULL) {
  475. OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_MALLOC_FAILURE);
  476. return 0;
  477. }
  478. new_buffer = 1;
  479. }
  480. if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp,
  481. buf_len, NULL)) {
  482. OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_EC_LIB);
  483. if (new_buffer) {
  484. OPENSSL_free(*outp);
  485. *outp = NULL;
  486. }
  487. return 0;
  488. }
  489. if (!new_buffer) {
  490. *outp += buf_len;
  491. }
  492. return buf_len;
  493. }