155714Skris/* evp_pkey.c */ 2280304Sjkim/* 3280304Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4280304Sjkim * 1999. 555714Skris */ 655714Skris/* ==================================================================== 7238405Sjkim * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 855714Skris * 955714Skris * Redistribution and use in source and binary forms, with or without 1055714Skris * modification, are permitted provided that the following conditions 1155714Skris * are met: 1255714Skris * 1355714Skris * 1. Redistributions of source code must retain the above copyright 14280304Sjkim * notice, this list of conditions and the following disclaimer. 1555714Skris * 1655714Skris * 2. Redistributions in binary form must reproduce the above copyright 1755714Skris * notice, this list of conditions and the following disclaimer in 1855714Skris * the documentation and/or other materials provided with the 1955714Skris * distribution. 2055714Skris * 2155714Skris * 3. All advertising materials mentioning features or use of this 2255714Skris * software must display the following acknowledgment: 2355714Skris * "This product includes software developed by the OpenSSL Project 2455714Skris * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2555714Skris * 2655714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2755714Skris * endorse or promote products derived from this software without 2855714Skris * prior written permission. For written permission, please contact 2955714Skris * licensing@OpenSSL.org. 3055714Skris * 3155714Skris * 5. Products derived from this software may not be called "OpenSSL" 3255714Skris * nor may "OpenSSL" appear in their names without prior written 3355714Skris * permission of the OpenSSL Project. 3455714Skris * 3555714Skris * 6. Redistributions of any form whatsoever must retain the following 3655714Skris * acknowledgment: 3755714Skris * "This product includes software developed by the OpenSSL Project 3855714Skris * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3955714Skris * 4055714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4155714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4255714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4355714Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4455714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4555714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4655714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4755714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4955714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5055714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5155714Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 5255714Skris * ==================================================================== 5355714Skris * 5455714Skris * This product includes cryptographic software written by Eric Young 5555714Skris * (eay@cryptsoft.com). This product includes software written by Tim 5655714Skris * Hudson (tjh@cryptsoft.com). 5755714Skris * 5855714Skris */ 5955714Skris 6055714Skris#include <stdio.h> 6155714Skris#include <stdlib.h> 6255714Skris#include "cryptlib.h" 6355714Skris#include <openssl/x509.h> 6455714Skris#include <openssl/rand.h> 65238405Sjkim#include "asn1_locl.h" 6655714Skris 6755714Skris/* Extract a private key from a PKCS8 structure */ 6855714Skris 69160814SsimonEVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) 7055714Skris{ 71280304Sjkim EVP_PKEY *pkey = NULL; 72280304Sjkim ASN1_OBJECT *algoid; 73280304Sjkim char obj_tmp[80]; 7455714Skris 75280304Sjkim if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8)) 76280304Sjkim return NULL; 77238405Sjkim 78280304Sjkim if (!(pkey = EVP_PKEY_new())) { 79280304Sjkim EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE); 80280304Sjkim return NULL; 81280304Sjkim } 8259191Skris 83280304Sjkim if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) { 84280304Sjkim EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); 85280304Sjkim i2t_ASN1_OBJECT(obj_tmp, 80, algoid); 86280304Sjkim ERR_add_error_data(2, "TYPE=", obj_tmp); 87280304Sjkim goto error; 88280304Sjkim } 89160814Ssimon 90280304Sjkim if (pkey->ameth->priv_decode) { 91280304Sjkim if (!pkey->ameth->priv_decode(pkey, p8)) { 92280304Sjkim EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_PRIVATE_KEY_DECODE_ERROR); 93280304Sjkim goto error; 94280304Sjkim } 95280304Sjkim } else { 96280304Sjkim EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED); 97280304Sjkim goto error; 98280304Sjkim } 99160814Ssimon 100280304Sjkim return pkey; 101160814Ssimon 102280304Sjkim error: 103280304Sjkim EVP_PKEY_free(pkey); 104280304Sjkim return NULL; 10555714Skris} 10655714Skris 10759191SkrisPKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) 10859191Skris{ 109280304Sjkim return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK); 11059191Skris} 11159191Skris 11255714Skris/* Turn a private key into a PKCS8 structure */ 11355714Skris 11459191SkrisPKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken) 11555714Skris{ 116280304Sjkim PKCS8_PRIV_KEY_INFO *p8; 11759191Skris 118280304Sjkim if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) { 119280304Sjkim EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE); 120280304Sjkim return NULL; 121280304Sjkim } 122280304Sjkim p8->broken = broken; 12355714Skris 124280304Sjkim if (pkey->ameth) { 125280304Sjkim if (pkey->ameth->priv_encode) { 126280304Sjkim if (!pkey->ameth->priv_encode(p8, pkey)) { 127280304Sjkim EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, 128280304Sjkim EVP_R_PRIVATE_KEY_ENCODE_ERROR); 129280304Sjkim goto error; 130280304Sjkim } 131280304Sjkim } else { 132280304Sjkim EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_METHOD_NOT_SUPPORTED); 133280304Sjkim goto error; 134280304Sjkim } 135280304Sjkim } else { 136280304Sjkim EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, 137280304Sjkim EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); 138280304Sjkim goto error; 139280304Sjkim } 140280304Sjkim RAND_add(p8->pkey->value.octet_string->data, 141280304Sjkim p8->pkey->value.octet_string->length, 0.0); 142280304Sjkim return p8; 143280304Sjkim error: 144280304Sjkim PKCS8_PRIV_KEY_INFO_free(p8); 145280304Sjkim return NULL; 14655714Skris} 14755714Skris 14855714SkrisPKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken) 14955714Skris{ 150280304Sjkim switch (broken) { 15155714Skris 152280304Sjkim case PKCS8_OK: 153280304Sjkim p8->broken = PKCS8_OK; 154280304Sjkim return p8; 155280304Sjkim break; 15655714Skris 157280304Sjkim case PKCS8_NO_OCTET: 158280304Sjkim p8->broken = PKCS8_NO_OCTET; 159280304Sjkim p8->pkey->type = V_ASN1_SEQUENCE; 160280304Sjkim return p8; 161280304Sjkim break; 16255714Skris 163280304Sjkim default: 164280304Sjkim EVPerr(EVP_F_PKCS8_SET_BROKEN, EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE); 165280304Sjkim return NULL; 166280304Sjkim } 16755714Skris} 16855714Skris 169160814Ssimon/* EVP_PKEY attribute functions */ 170160814Ssimon 171160814Ssimonint EVP_PKEY_get_attr_count(const EVP_PKEY *key) 172160814Ssimon{ 173280304Sjkim return X509at_get_attr_count(key->attributes); 174160814Ssimon} 175160814Ssimon 176280304Sjkimint EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos) 177160814Ssimon{ 178280304Sjkim return X509at_get_attr_by_NID(key->attributes, nid, lastpos); 179160814Ssimon} 180160814Ssimon 181160814Ssimonint EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj, 182280304Sjkim int lastpos) 183160814Ssimon{ 184280304Sjkim return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos); 185160814Ssimon} 186160814Ssimon 187160814SsimonX509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc) 188160814Ssimon{ 189280304Sjkim return X509at_get_attr(key->attributes, loc); 190160814Ssimon} 191160814Ssimon 192160814SsimonX509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc) 193160814Ssimon{ 194280304Sjkim return X509at_delete_attr(key->attributes, loc); 195160814Ssimon} 196160814Ssimon 197160814Ssimonint EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr) 198160814Ssimon{ 199280304Sjkim if (X509at_add1_attr(&key->attributes, attr)) 200280304Sjkim return 1; 201280304Sjkim return 0; 202160814Ssimon} 203160814Ssimon 204160814Ssimonint EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, 205280304Sjkim const ASN1_OBJECT *obj, int type, 206280304Sjkim const unsigned char *bytes, int len) 207160814Ssimon{ 208280304Sjkim if (X509at_add1_attr_by_OBJ(&key->attributes, obj, type, bytes, len)) 209280304Sjkim return 1; 210280304Sjkim return 0; 211160814Ssimon} 212160814Ssimon 213160814Ssimonint EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, 214280304Sjkim int nid, int type, 215280304Sjkim const unsigned char *bytes, int len) 216160814Ssimon{ 217280304Sjkim if (X509at_add1_attr_by_NID(&key->attributes, nid, type, bytes, len)) 218280304Sjkim return 1; 219280304Sjkim return 0; 220160814Ssimon} 221160814Ssimon 222160814Ssimonint EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, 223280304Sjkim const char *attrname, int type, 224280304Sjkim const unsigned char *bytes, int len) 225160814Ssimon{ 226280304Sjkim if (X509at_add1_attr_by_txt(&key->attributes, attrname, type, bytes, len)) 227280304Sjkim return 1; 228280304Sjkim return 0; 229160814Ssimon} 230