blob: 310af83f001beb6f13dba6f7bc9c0c7ef1486cbf [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 * project 1999.
3 */
4/* ====================================================================
5 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. All advertising materials mentioning features or use of this
20 * software must display the following acknowledgment:
21 * "This product includes software developed by the OpenSSL Project
22 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 *
24 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 * endorse or promote products derived from this software without
26 * prior written permission. For written permission, please contact
27 * licensing@OpenSSL.org.
28 *
29 * 5. Products derived from this software may not be called "OpenSSL"
30 * nor may "OpenSSL" appear in their names without prior written
31 * permission of the OpenSSL Project.
32 *
33 * 6. Redistributions of any form whatsoever must retain the following
34 * acknowledgment:
35 * "This product includes software developed by the OpenSSL Project
36 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 * OF THE POSSIBILITY OF SUCH DAMAGE.
50 * ====================================================================
51 *
52 * This product includes cryptographic software written by Eric Young
53 * (eay@cryptsoft.com). This product includes software written by Tim
54 * Hudson (tjh@cryptsoft.com). */
55
56#include <openssl/pkcs8.h>
57
58#include <openssl/asn1.h>
59#include <openssl/bn.h>
60#include <openssl/cipher.h>
61#include <openssl/digest.h>
62#include <openssl/err.h>
63#include <openssl/mem.h>
64#include <openssl/x509.h>
65
66#include "../evp/internal.h"
67
68
69#define PKCS12_KEY_ID 1
70#define PKCS12_IV_ID 2
71
72static int ascii_to_ucs2(const char *ascii, size_t ascii_len,
73 uint8_t **out, size_t *out_len) {
74 uint8_t *unitmp;
75 size_t ulen, i;
76
77 ulen = ascii_len * 2 + 2;
78 if (ulen < ascii_len) {
79 return 0;
80 }
81 unitmp = OPENSSL_malloc(ulen);
82 if (unitmp == NULL) {
83 return 0;
84 }
85 for (i = 0; i < ulen - 2; i += 2) {
86 unitmp[i] = 0;
87 unitmp[i + 1] = ascii[i >> 1];
88 }
89
90 /* Make result double null terminated */
91 unitmp[ulen - 2] = 0;
92 unitmp[ulen - 1] = 0;
93 *out_len = ulen;
94 *out = unitmp;
95 return 1;
96}
97
98static int pkcs12_key_gen_uni(uint8_t *pass, size_t pass_len, uint8_t *salt,
99 size_t salt_len, int id, int iterations,
100 size_t out_len, uint8_t *out,
101 const EVP_MD *md_type) {
102 uint8_t *B, *D, *I, *p, *Ai;
103 int Slen, Plen, Ilen, Ijlen;
104 int i, j, v;
105 size_t u;
106 int ret = 0;
107 BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */
108 EVP_MD_CTX ctx;
109
110 EVP_MD_CTX_init(&ctx);
111 v = EVP_MD_block_size(md_type);
112 u = EVP_MD_size(md_type);
113 D = OPENSSL_malloc(v);
114 Ai = OPENSSL_malloc(u);
115 B = OPENSSL_malloc(v + 1);
116 Slen = v * ((salt_len + v - 1) / v);
117 if (pass_len)
118 Plen = v * ((pass_len + v - 1) / v);
119 else
120 Plen = 0;
121 Ilen = Slen + Plen;
122 I = OPENSSL_malloc(Ilen);
123 Ij = BN_new();
124 Bpl1 = BN_new();
125 if (!D || !Ai || !B || !I || !Ij || !Bpl1)
126 goto err;
127 for (i = 0; i < v; i++)
128 D[i] = id;
129 p = I;
130 for (i = 0; i < Slen; i++)
131 *p++ = salt[i % salt_len];
132 for (i = 0; i < Plen; i++)
133 *p++ = pass[i % pass_len];
134 for (;;) {
135 if (!EVP_DigestInit_ex(&ctx, md_type, NULL) ||
136 !EVP_DigestUpdate(&ctx, D, v) ||
137 !EVP_DigestUpdate(&ctx, I, Ilen) ||
138 !EVP_DigestFinal_ex(&ctx, Ai, NULL)) {
139 goto err;
140 }
141 for (j = 1; j < iterations; j++) {
142 if (!EVP_DigestInit_ex(&ctx, md_type, NULL) ||
143 !EVP_DigestUpdate(&ctx, Ai, u) ||
144 !EVP_DigestFinal_ex(&ctx, Ai, NULL)) {
145 goto err;
146 }
147 }
148 memcpy(out, Ai, out_len < u ? out_len : u);
149 if (u >= out_len) {
150 ret = 1;
151 goto end;
152 }
153 out_len -= u;
154 out += u;
155 for (j = 0; j < v; j++)
156 B[j] = Ai[j % u];
157 /* Work out B + 1 first then can use B as tmp space */
158 if (!BN_bin2bn(B, v, Bpl1))
159 goto err;
160 if (!BN_add_word(Bpl1, 1))
161 goto err;
162 for (j = 0; j < Ilen; j += v) {
163 if (!BN_bin2bn(I + j, v, Ij))
164 goto err;
165 if (!BN_add(Ij, Ij, Bpl1))
166 goto err;
167 if (!BN_bn2bin(Ij, B))
168 goto err;
169 Ijlen = BN_num_bytes(Ij);
170 /* If more than 2^(v*8) - 1 cut off MSB */
171 if (Ijlen > v) {
172 if (!BN_bn2bin(Ij, B))
173 goto err;
174 memcpy(I + j, B + 1, v);
175 /* If less than v bytes pad with zeroes */
176 } else if (Ijlen < v) {
177 memset(I + j, 0, v - Ijlen);
178 if (!BN_bn2bin(Ij, I + j + v - Ijlen))
179 goto err;
180 } else if (!BN_bn2bin(Ij, I + j)) {
181 goto err;
182 }
183 }
184 }
185
186err:
187 OPENSSL_PUT_ERROR(PKCS8, pkcs12_key_gen_uni, ERR_R_MALLOC_FAILURE);
188
189end:
190 OPENSSL_free(Ai);
191 OPENSSL_free(B);
192 OPENSSL_free(D);
193 OPENSSL_free(I);
194 BN_free(Ij);
195 BN_free(Bpl1);
196 EVP_MD_CTX_cleanup(&ctx);
197
198 return ret;
199}
200
201static int pkcs12_key_gen_asc(const char *pass, size_t pass_len, uint8_t *salt,
202 size_t salt_len, int id, int iterations,
203 int out_len, uint8_t *out,
204 const EVP_MD *md_type) {
205 int ret;
206 uint8_t *ucs2_pass = NULL;
207 size_t ucs2_pass_len = 0;
208
209 if (pass && !ascii_to_ucs2(pass, pass_len, &ucs2_pass, &ucs2_pass_len)) {
210 OPENSSL_PUT_ERROR(PKCS8, pkcs12_key_gen_asc, PKCS8_R_DECODE_ERROR);
211 return 0;
212 }
213 ret = pkcs12_key_gen_uni(ucs2_pass, ucs2_pass_len, salt, salt_len, id,
214 iterations, out_len, out, md_type);
215
216 if (ucs2_pass) {
217 OPENSSL_cleanse(ucs2_pass, ucs2_pass_len);
218 OPENSSL_free(ucs2_pass);
219 }
220
221 return ret;
222}
223
224static int pkcs12_pbe_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
225 size_t pass_len, ASN1_TYPE *param,
226 const EVP_CIPHER *cipher, const EVP_MD *md,
227 int is_encrypt) {
228 PBEPARAM *pbe;
229 int salt_len, iterations, ret;
230 uint8_t *salt;
231 const uint8_t *pbuf;
232 uint8_t key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
233
234 /* Extract useful info from parameter */
235 if (param == NULL || param->type != V_ASN1_SEQUENCE ||
236 param->value.sequence == NULL) {
237 OPENSSL_PUT_ERROR(PKCS8, pkcs12_pbe_keyivgen, PKCS8_R_DECODE_ERROR);
238 return 0;
239 }
240
241 pbuf = param->value.sequence->data;
242 pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length);
243 if (pbe == NULL) {
244 OPENSSL_PUT_ERROR(PKCS8, pkcs12_pbe_keyivgen, PKCS8_R_DECODE_ERROR);
245 return 0;
246 }
247
248 if (!pbe->iter) {
249 iterations = 1;
250 } else {
251 iterations = ASN1_INTEGER_get(pbe->iter);
252 }
253 salt = pbe->salt->data;
254 salt_len = pbe->salt->length;
255 if (!pkcs12_key_gen_asc(pass, pass_len, salt, salt_len, PKCS12_KEY_ID,
256 iterations, EVP_CIPHER_key_length(cipher), key, md)) {
257 OPENSSL_PUT_ERROR(PKCS8, pkcs12_pbe_keyivgen, PKCS8_R_KEY_GEN_ERROR);
258 PBEPARAM_free(pbe);
259 return 0;
260 }
261 if (!pkcs12_key_gen_asc(pass, pass_len, salt, salt_len, PKCS12_IV_ID,
262 iterations, EVP_CIPHER_iv_length(cipher), iv, md)) {
263 OPENSSL_PUT_ERROR(PKCS8, pkcs12_pbe_keyivgen, PKCS8_R_KEY_GEN_ERROR);
264 PBEPARAM_free(pbe);
265 return 0;
266 }
267 PBEPARAM_free(pbe);
268 ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, is_encrypt);
269 OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
270 OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
271 return ret;
272}
273
274typedef int (*keygen_func)(EVP_CIPHER_CTX *ctx, const char *pass,
275 size_t pass_len, ASN1_TYPE *param,
276 const EVP_CIPHER *cipher, const EVP_MD *md,
277 int is_encrypt);
278
279struct pbe_suite {
280 int pbe_nid;
281 int cipher_nid;
282 int md_nid;
283 keygen_func keygen;
284};
285
286static const struct pbe_suite kBuiltinPBE[] = {
287 {
288 NID_pbe_WithSHA1And128BitRC4, NID_rc4, NID_sha1, pkcs12_pbe_keyivgen,
289 },
290 {
291 NID_pbe_WithSHA1And3_Key_TripleDES_CBC, NID_des_ede3_cbc, NID_sha1,
292 pkcs12_pbe_keyivgen,
293 },
294};
295
296static int pbe_cipher_init(ASN1_OBJECT *pbe_obj, const char *pass,
297 size_t pass_len, ASN1_TYPE *param,
298 EVP_CIPHER_CTX *ctx, int is_encrypt) {
299 const EVP_CIPHER *cipher;
300 const EVP_MD *md;
301 unsigned i;
302
303 const struct pbe_suite *suite = NULL;
304 const int pbe_nid = OBJ_obj2nid(pbe_obj);
305
306 for (i = 0; i < sizeof(kBuiltinPBE) / sizeof(struct pbe_suite); i++) {
307 suite = &kBuiltinPBE[i];
308 if (suite->pbe_nid == pbe_nid) {
309 break;
310 }
311 }
312
313 if (suite == NULL) {
314 char obj_str[80];
315 OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_UNKNOWN_ALGORITHM);
316 if (!pbe_obj) {
317 strncpy(obj_str, "NULL", sizeof(obj_str));
318 } else {
319 i2t_ASN1_OBJECT(obj_str, sizeof(obj_str), pbe_obj);
320 }
321 ERR_add_error_data(2, "TYPE=", obj_str);
322 return 0;
323 }
324
325 if (suite->cipher_nid == -1) {
326 cipher = NULL;
327 } else {
328 cipher = EVP_get_cipherbynid(suite->cipher_nid);
329 if (!cipher) {
330 OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_UNKNOWN_CIPHER);
331 return 0;
332 }
333 }
334
335 if (suite->md_nid == -1) {
336 md = NULL;
337 } else {
338 md = EVP_get_digestbynid(suite->md_nid);
339 if (!md) {
340 OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_UNKNOWN_DIGEST);
341 return 0;
342 }
343 }
344
345 if (!suite->keygen(ctx, pass, pass_len, param, cipher, md, is_encrypt)) {
346 OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_KEYGEN_FAILURE);
347 return 0;
348 }
349
350 return 1;
351}
352
353static int pbe_crypt(const X509_ALGOR *algor, const char *pass, size_t pass_len,
354 uint8_t *in, size_t in_len, uint8_t **out, size_t *out_len,
355 int is_encrypt) {
356 uint8_t *buf;
357 int n, ret = 0;
358 EVP_CIPHER_CTX ctx;
359 unsigned block_size;
360
361 EVP_CIPHER_CTX_init(&ctx);
362
363 if (!pbe_cipher_init(algor->algorithm, pass, pass_len, algor->parameter, &ctx,
364 is_encrypt)) {
365 OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, PKCS8_R_UNKNOWN_CIPHER_ALGORITHM);
366 return 0;
367 }
368 block_size = EVP_CIPHER_CTX_block_size(&ctx);
369
370 if (in_len + block_size < in_len) {
371 OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, PKCS8_R_TOO_LONG);
372 goto err;
373 }
374
375 buf = OPENSSL_malloc(in_len + block_size);
376 if (buf == NULL) {
377 OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, ERR_R_MALLOC_FAILURE);
378 goto err;
379 }
380
381 if (!EVP_CipherUpdate(&ctx, buf, &n, in, in_len)) {
382 OPENSSL_free(buf);
383 OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, ERR_R_EVP_LIB);
384 goto err;
385 }
386 *out_len = n;
387
388 if (!EVP_CipherFinal_ex(&ctx, buf + n, &n)) {
389 OPENSSL_free(buf);
390 OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, ERR_R_EVP_LIB);
391 goto err;
392 }
393 *out_len += n;
394 *out = buf;
395 ret = 1;
396
397err:
398 EVP_CIPHER_CTX_cleanup(&ctx);
399 return ret;
400}
401
402static void *pkcs12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
403 const char *pass, size_t pass_len,
404 ASN1_OCTET_STRING *oct) {
405 uint8_t *out;
406 const uint8_t *p;
407 void *ret;
408 size_t out_len;
409
410 if (!pbe_crypt(algor, pass, pass_len, oct->data, oct->length, &out, &out_len,
411 0 /* decrypt */)) {
412 OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_decrypt_d2i, PKCS8_R_CRYPT_ERROR);
413 return NULL;
414 }
415 p = out;
416 ret = ASN1_item_d2i(NULL, &p, out_len, it);
417 OPENSSL_cleanse(out, out_len);
418 if (!ret) {
419 OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_decrypt_d2i, PKCS8_R_DECODE_ERROR);
420 }
421 OPENSSL_free(out);
422 return ret;
423}
424
425PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8, const char *pass,
426 int pass_len) {
427 if (pass && pass_len == -1) {
428 pass_len = strlen(pass);
429 }
430 return pkcs12_item_decrypt_d2i(pkcs8->algor,
431 ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass,
432 pass_len, pkcs8->digest);
433}
434
435static ASN1_OCTET_STRING *pkcs12_item_i2d_encrypt(X509_ALGOR *algor,
436 const ASN1_ITEM *it,
437 const char *pass,
438 size_t passlen, void *obj) {
439 ASN1_OCTET_STRING *oct;
440 uint8_t *in = NULL;
441 int in_len;
442 size_t crypt_len;
443
444 oct = M_ASN1_OCTET_STRING_new();
445 if (oct == NULL) {
446 OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_i2d_encrypt, ERR_R_MALLOC_FAILURE);
447 return NULL;
448 }
449 in_len = ASN1_item_i2d(obj, &in, it);
450 if (!in) {
451 OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_i2d_encrypt, PKCS8_R_ENCODE_ERROR);
452 return NULL;
453 }
454 if (!pbe_crypt(algor, pass, passlen, in, in_len, &oct->data, &crypt_len,
455 1 /* encrypt */)) {
456 OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_i2d_encrypt, PKCS8_R_ENCRYPT_ERROR);
457 OPENSSL_free(in);
458 return NULL;
459 }
460 oct->length = crypt_len;
461 OPENSSL_cleanse(in, in_len);
462 OPENSSL_free(in);
463 return oct;
464}
465
466X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass,
467 int pass_len, uint8_t *salt, size_t salt_len,
468 int iterations, PKCS8_PRIV_KEY_INFO *p8inf) {
469 X509_SIG *pkcs8 = NULL;
470 X509_ALGOR *pbe;
471
472 if (pass && pass_len == -1) {
473 pass_len = strlen(pass);
474 }
475
476 pkcs8 = X509_SIG_new();
477 if (pkcs8 == NULL) {
478 OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt, ERR_R_MALLOC_FAILURE);
479 goto err;
480 }
481
482 if (pbe_nid == -1) {
483 pbe = PKCS5_pbe2_set(cipher, iterations, salt, salt_len);
484 } else {
485 pbe = PKCS5_pbe_set(pbe_nid, iterations, salt, salt_len);
486 }
487
488 if (!pbe) {
489 OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt, ERR_R_ASN1_LIB);
490 goto err;
491 }
492
493 X509_ALGOR_free(pkcs8->algor);
494 pkcs8->algor = pbe;
495 M_ASN1_OCTET_STRING_free(pkcs8->digest);
496 pkcs8->digest = pkcs12_item_i2d_encrypt(
497 pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass, pass_len, p8inf);
498 if (!pkcs8->digest) {
499 OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt, PKCS8_R_ENCRYPT_ERROR);
500 goto err;
501 }
502
503 return pkcs8;
504
505err:
506 X509_SIG_free(pkcs8);
507 return NULL;
508}
509
510EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) {
511 EVP_PKEY *pkey = NULL;
512 ASN1_OBJECT *algoid;
513 char obj_tmp[80];
514
515 if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
516 return NULL;
517
518 pkey = EVP_PKEY_new();
519 if (pkey == NULL) {
520 OPENSSL_PUT_ERROR(PKCS8, EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE);
521 return NULL;
522 }
523
524 if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
525 OPENSSL_PUT_ERROR(PKCS8, EVP_PKCS82PKEY,
526 PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
527 i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
528 ERR_add_error_data(2, "TYPE=", obj_tmp);
529 goto error;
530 }
531
532 if (pkey->ameth->priv_decode) {
533 if (!pkey->ameth->priv_decode(pkey, p8)) {
534 OPENSSL_PUT_ERROR(PKCS8, EVP_PKCS82PKEY, PKCS8_R_PRIVATE_KEY_DECODE_ERROR);
535 goto error;
536 }
537 } else {
538 OPENSSL_PUT_ERROR(PKCS8, EVP_PKCS82PKEY, PKCS8_R_METHOD_NOT_SUPPORTED);
539 goto error;
540 }
541
542 return pkey;
543
544error:
545 EVP_PKEY_free(pkey);
546 return NULL;
547}
548
549PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) {
550 PKCS8_PRIV_KEY_INFO *p8;
551
552 p8 = PKCS8_PRIV_KEY_INFO_new();
553 if (p8 == NULL) {
554 OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
555 return NULL;
556 }
557 p8->broken = PKCS8_OK;
558
559 if (pkey->ameth) {
560 if (pkey->ameth->priv_encode) {
561 if (!pkey->ameth->priv_encode(p8, pkey)) {
562 OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8,
563 PKCS8_R_PRIVATE_KEY_ENCODE_ERROR);
564 goto error;
565 }
566 } else {
567 OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8, PKCS8_R_METHOD_NOT_SUPPORTED);
568 goto error;
569 }
570 } else {
571 OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8,
572 PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
573 goto error;
574 }
575 return p8;
576
577error:
578 PKCS8_PRIV_KEY_INFO_free(p8);
579 return NULL;
580}