1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * All rights reserved. 3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This package is an SSL implementation written 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * by Eric Young (eay@cryptsoft.com). 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The implementation was written so as to conform with Netscapes SSL. 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This library is free for commercial and non-commercial use as long as 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the following conditions are aheared to. The following conditions 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * apply to all code found in this distribution, be it the RC4, RSA, 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * included with this distribution is covered by the same copyright terms 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright remains Eric Young's, and as such any Copyright notices in 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the code are not to be removed. 17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * If this package is used in a product, Eric Young should be given attribution 18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * as the author of the parts of the library used. 19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This can be in the form of a textual message at program startup or 20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * in documentation (online or textual) provided with the package. 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without 23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions 24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met: 25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the copyright 26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer. 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright 28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer in the 29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * documentation and/or other materials provided with the distribution. 30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this software 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * must display the following acknowledgement: 32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes cryptographic software written by 33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Eric Young (eay@cryptsoft.com)" 34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The word 'cryptographic' can be left out if the rouines from the library 35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * being used are not cryptographic related :-). 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. If you include any Windows specific code (or a derivative thereof) from 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the apps directory (application code) you must include an acknowledgement: 38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SUCH DAMAGE. 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * The licence and distribution terms for any publically available version or 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * derivative of this code cannot be changed. i.e. this code cannot simply be 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * copied and put under another distribution licence 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * [including the GNU Public Licence.] */ 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 57d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/pem.h> 58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/buf.h> 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/err.h> 61d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/evp.h> 62e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <openssl/mem.h> 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/obj.h> 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/pkcs8.h> 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/rand.h> 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/x509.h> 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 69d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int nid, const EVP_CIPHER *enc, 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *kstr, int klen, 72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pem_password_cb *cb, void *u); 73d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, 74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int nid, const EVP_CIPHER *enc, 75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *kstr, int klen, 76d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pem_password_cb *cb, void *u); 77d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* These functions write a private key in PKCS#8 format: it is a "drop in" 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc' 80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * is NULL then it uses the unencrypted private key form. The 'nid' versions 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0. 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */ 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 84d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *kstr, int klen, 86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pem_password_cb *cb, void *u) 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *kstr, int klen, 93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pem_password_cb *cb, void *u) 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); 96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *kstr, int klen, 100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pem_password_cb *cb, void *u) 101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); 103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 105d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, 106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *kstr, int klen, 107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pem_password_cb *cb, void *u) 108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); 110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 112d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, 113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *kstr, int klen, 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pem_password_cb *cb, void *u) 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley X509_SIG *p8; 117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley PKCS8_PRIV_KEY_INFO *p8inf; 118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char buf[PEM_BUFSIZE]; 119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int ret; 120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!(p8inf = EVP_PKEY2PKCS8(x))) { 121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(PEM, do_pk8pkey, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); 122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(enc || (nid != -1)) { 125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!kstr) { 126d9e397b599b13d642138480a28c14db7a136bf0Adam Langley klen = 0; 12753b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley if (!cb) cb = PEM_def_callback; 12853b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley klen = cb(buf, PEM_BUFSIZE, 1, u); 129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(klen <= 0) { 130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(PEM, do_pk8pkey, PEM_R_READ_KEY); 131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley PKCS8_PRIV_KEY_INFO_free(p8inf); 132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley kstr = buf; 136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); 138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(kstr == buf) OPENSSL_cleanse(buf, klen); 139d9e397b599b13d642138480a28c14db7a136bf0Adam Langley PKCS8_PRIV_KEY_INFO_free(p8inf); 140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(isder) ret = i2d_PKCS8_bio(bp, p8); 141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley else ret = PEM_write_bio_PKCS8(bp, p8); 142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley X509_SIG_free(p8); 143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else { 145d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(isder) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); 146d9e397b599b13d642138480a28c14db7a136bf0Adam Langley else ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); 147d9e397b599b13d642138480a28c14db7a136bf0Adam Langley PKCS8_PRIV_KEY_INFO_free(p8inf); 148d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 151d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 152d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyEVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) 153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley PKCS8_PRIV_KEY_INFO *p8inf = NULL; 155d9e397b599b13d642138480a28c14db7a136bf0Adam Langley X509_SIG *p8 = NULL; 156d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int klen; 157d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_PKEY *ret; 158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char psbuf[PEM_BUFSIZE]; 159d9e397b599b13d642138480a28c14db7a136bf0Adam Langley p8 = d2i_PKCS8_bio(bp, NULL); 160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!p8) return NULL; 161d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley klen = 0; 16353b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley if (!cb) cb = PEM_def_callback; 16453b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley klen=cb(psbuf,PEM_BUFSIZE,0,u); 165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (klen <= 0) { 166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(PEM, d2i_PKCS8PrivateKey_bio, PEM_R_BAD_PASSWORD_READ); 167d9e397b599b13d642138480a28c14db7a136bf0Adam Langley X509_SIG_free(p8); 168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 169d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley p8inf = PKCS8_decrypt(p8, psbuf, klen); 171d9e397b599b13d642138480a28c14db7a136bf0Adam Langley X509_SIG_free(p8); 172d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!p8inf) return NULL; 173d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret = EVP_PKCS82PKEY(p8inf); 174d9e397b599b13d642138480a28c14db7a136bf0Adam Langley PKCS8_PRIV_KEY_INFO_free(p8inf); 175d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!ret) return NULL; 176d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(x) { 177d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(*x) EVP_PKEY_free(*x); 178d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *x = ret; 179d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 180d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 181d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 182d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 183d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#ifndef OPENSSL_NO_FP_API 184d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 185d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, 186d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *kstr, int klen, 187d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pem_password_cb *cb, void *u) 188d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 189d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); 190d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 191d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 192d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, 193d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *kstr, int klen, 194d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pem_password_cb *cb, void *u) 195d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 196d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); 197d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 198d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 199d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, 200d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *kstr, int klen, 201d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pem_password_cb *cb, void *u) 202d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 203d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); 204d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 205d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 206d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, 207d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *kstr, int klen, pem_password_cb *cb, void *u) 208d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 209d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); 210d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 211d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 212d9e397b599b13d642138480a28c14db7a136bf0Adam Langleystatic int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, 213d9e397b599b13d642138480a28c14db7a136bf0Adam Langley char *kstr, int klen, 214d9e397b599b13d642138480a28c14db7a136bf0Adam Langley pem_password_cb *cb, void *u) 215d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 216d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIO *bp; 217d9e397b599b13d642138480a28c14db7a136bf0Adam Langley int ret; 218d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { 219d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(PEM, do_pk8pkey_fp, ERR_R_BUF_LIB); 220d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return(0); 221d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u); 223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIO_free(bp); 224d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 225d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 226d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 227d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyEVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) 228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley{ 229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIO *bp; 230d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_PKEY *ret; 231d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { 232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley OPENSSL_PUT_ERROR(PEM, d2i_PKCS8PrivateKey_fp, ERR_R_BUF_LIB); 233d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return NULL; 234d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 235d9e397b599b13d642138480a28c14db7a136bf0Adam Langley ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u); 236d9e397b599b13d642138480a28c14db7a136bf0Adam Langley BIO_free(bp); 237d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return ret; 238d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 239d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 240d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif 241d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 242d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyIMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG) 243d9e397b599b13d642138480a28c14db7a136bf0Adam LangleyIMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, 244d9e397b599b13d642138480a28c14db7a136bf0Adam Langley PKCS8_PRIV_KEY_INFO) 245