p12_attr.c revision 55714
155714Skris/* p12_attr.c */
255714Skris/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
355714Skris * project 1999.
455714Skris */
555714Skris/* ====================================================================
655714Skris * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
755714Skris *
855714Skris * Redistribution and use in source and binary forms, with or without
955714Skris * modification, are permitted provided that the following conditions
1055714Skris * are met:
1155714Skris *
1255714Skris * 1. Redistributions of source code must retain the above copyright
1355714Skris *    notice, this list of conditions and the following disclaimer.
1455714Skris *
1555714Skris * 2. Redistributions in binary form must reproduce the above copyright
1655714Skris *    notice, this list of conditions and the following disclaimer in
1755714Skris *    the documentation and/or other materials provided with the
1855714Skris *    distribution.
1955714Skris *
2055714Skris * 3. All advertising materials mentioning features or use of this
2155714Skris *    software must display the following acknowledgment:
2255714Skris *    "This product includes software developed by the OpenSSL Project
2355714Skris *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2455714Skris *
2555714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2655714Skris *    endorse or promote products derived from this software without
2755714Skris *    prior written permission. For written permission, please contact
2855714Skris *    licensing@OpenSSL.org.
2955714Skris *
3055714Skris * 5. Products derived from this software may not be called "OpenSSL"
3155714Skris *    nor may "OpenSSL" appear in their names without prior written
3255714Skris *    permission of the OpenSSL Project.
3355714Skris *
3455714Skris * 6. Redistributions of any form whatsoever must retain the following
3555714Skris *    acknowledgment:
3655714Skris *    "This product includes software developed by the OpenSSL Project
3755714Skris *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
3855714Skris *
3955714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4055714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4155714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4255714Skris * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4355714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4455714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4555714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4655714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4755714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4855714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4955714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5055714Skris * OF THE POSSIBILITY OF SUCH DAMAGE.
5155714Skris * ====================================================================
5255714Skris *
5355714Skris * This product includes cryptographic software written by Eric Young
5455714Skris * (eay@cryptsoft.com).  This product includes software written by Tim
5555714Skris * Hudson (tjh@cryptsoft.com).
5655714Skris *
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include "cryptlib.h"
6155714Skris#include <openssl/pkcs12.h>
6255714Skris
6355714Skris/* Add a local keyid to a safebag */
6455714Skris
6555714Skrisint PKCS12_add_localkeyid (PKCS12_SAFEBAG *bag, unsigned char *name,
6655714Skris	     int namelen)
6755714Skris{
6855714Skris	X509_ATTRIBUTE *attrib;
6955714Skris	ASN1_BMPSTRING *oct;
7055714Skris	ASN1_TYPE *keyid;
7155714Skris	if (!(keyid = ASN1_TYPE_new ())) {
7255714Skris		PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE);
7355714Skris		return 0;
7455714Skris	}
7555714Skris	keyid->type = V_ASN1_OCTET_STRING;
7655714Skris	if (!(oct = ASN1_OCTET_STRING_new())) {
7755714Skris		PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE);
7855714Skris		return 0;
7955714Skris	}
8055714Skris	if (!ASN1_OCTET_STRING_set(oct, name, namelen)) {
8155714Skris		PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE);
8255714Skris		return 0;
8355714Skris	}
8455714Skris	keyid->value.octet_string = oct;
8555714Skris	if (!(attrib = X509_ATTRIBUTE_new ())) {
8655714Skris		PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE);
8755714Skris		return 0;
8855714Skris	}
8955714Skris	attrib->object = OBJ_nid2obj(NID_localKeyID);
9055714Skris	if (!(attrib->value.set = sk_ASN1_TYPE_new(NULL))) {
9155714Skris		PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE);
9255714Skris		return 0;
9355714Skris	}
9455714Skris	sk_ASN1_TYPE_push (attrib->value.set,keyid);
9555714Skris	attrib->set = 1;
9655714Skris	if (!bag->attrib && !(bag->attrib = sk_X509_ATTRIBUTE_new (NULL))) {
9755714Skris		PKCS12err(PKCS12_F_PKCS12_ADD_LOCALKEYID, ERR_R_MALLOC_FAILURE);
9855714Skris		return 0;
9955714Skris	}
10055714Skris	sk_X509_ATTRIBUTE_push (bag->attrib, attrib);
10155714Skris	return 1;
10255714Skris}
10355714Skris
10455714Skris/* Add key usage to PKCS#8 structure */
10555714Skris
10655714Skrisint PKCS8_add_keyusage (PKCS8_PRIV_KEY_INFO *p8, int usage)
10755714Skris{
10855714Skris	X509_ATTRIBUTE *attrib;
10955714Skris	ASN1_BIT_STRING *bstr;
11055714Skris	ASN1_TYPE *keyid;
11155714Skris	unsigned char us_val;
11255714Skris	us_val = (unsigned char) usage;
11355714Skris	if (!(keyid = ASN1_TYPE_new ())) {
11455714Skris		PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE);
11555714Skris		return 0;
11655714Skris	}
11755714Skris	keyid->type = V_ASN1_BIT_STRING;
11855714Skris	if (!(bstr = ASN1_BIT_STRING_new())) {
11955714Skris		PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE);
12055714Skris		return 0;
12155714Skris	}
12255714Skris	if (!ASN1_BIT_STRING_set(bstr, &us_val, 1)) {
12355714Skris		PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE);
12455714Skris		return 0;
12555714Skris	}
12655714Skris	keyid->value.bit_string = bstr;
12755714Skris	if (!(attrib = X509_ATTRIBUTE_new ())) {
12855714Skris		PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE);
12955714Skris		return 0;
13055714Skris	}
13155714Skris	attrib->object = OBJ_nid2obj(NID_key_usage);
13255714Skris	if (!(attrib->value.set = sk_ASN1_TYPE_new(NULL))) {
13355714Skris		PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE);
13455714Skris		return 0;
13555714Skris	}
13655714Skris	sk_ASN1_TYPE_push (attrib->value.set,keyid);
13755714Skris	attrib->set = 1;
13855714Skris	if (!p8->attributes
13955714Skris	    && !(p8->attributes = sk_X509_ATTRIBUTE_new (NULL))) {
14055714Skris		PKCS12err(PKCS12_F_PKCS8_ADD_KEYUSAGE, ERR_R_MALLOC_FAILURE);
14155714Skris		return 0;
14255714Skris	}
14355714Skris	sk_X509_ATTRIBUTE_push (p8->attributes, attrib);
14455714Skris	return 1;
14555714Skris}
14655714Skris
14755714Skris/* Add a friendlyname to a safebag */
14855714Skris
14955714Skrisint PKCS12_add_friendlyname_asc (PKCS12_SAFEBAG *bag, const char *name,
15055714Skris				 int namelen)
15155714Skris{
15255714Skris	unsigned char *uniname;
15355714Skris	int ret, unilen;
15455714Skris	if (!asc2uni(name, &uniname, &unilen)) {
15555714Skris		PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC,
15655714Skris							ERR_R_MALLOC_FAILURE);
15755714Skris		return 0;
15855714Skris	}
15955714Skris	ret = PKCS12_add_friendlyname_uni (bag, uniname, unilen);
16055714Skris	Free(uniname);
16155714Skris	return ret;
16255714Skris}
16355714Skris
16455714Skris
16555714Skrisint PKCS12_add_friendlyname_uni (PKCS12_SAFEBAG *bag,
16655714Skris				 const unsigned char *name, int namelen)
16755714Skris{
16855714Skris	X509_ATTRIBUTE *attrib;
16955714Skris	ASN1_BMPSTRING *bmp;
17055714Skris	ASN1_TYPE *fname;
17155714Skris	/* Zap ending double null if included */
17255714Skris	if(!name[namelen - 1] && !name[namelen - 2]) namelen -= 2;
17355714Skris	if (!(fname = ASN1_TYPE_new ())) {
17455714Skris		PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI,
17555714Skris							ERR_R_MALLOC_FAILURE);
17655714Skris		return 0;
17755714Skris	}
17855714Skris	fname->type = V_ASN1_BMPSTRING;
17955714Skris	if (!(bmp = ASN1_BMPSTRING_new())) {
18055714Skris		PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI,
18155714Skris							ERR_R_MALLOC_FAILURE);
18255714Skris		return 0;
18355714Skris	}
18455714Skris	if (!(bmp->data = Malloc (namelen))) {
18555714Skris		PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI,
18655714Skris							ERR_R_MALLOC_FAILURE);
18755714Skris		return 0;
18855714Skris	}
18955714Skris	memcpy (bmp->data, name, namelen);
19055714Skris	bmp->length = namelen;
19155714Skris	fname->value.bmpstring = bmp;
19255714Skris	if (!(attrib = X509_ATTRIBUTE_new ())) {
19355714Skris		PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI,
19455714Skris							ERR_R_MALLOC_FAILURE);
19555714Skris		return 0;
19655714Skris	}
19755714Skris	attrib->object = OBJ_nid2obj(NID_friendlyName);
19855714Skris	if (!(attrib->value.set = sk_ASN1_TYPE_new(NULL))) {
19955714Skris		PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME,
20055714Skris							ERR_R_MALLOC_FAILURE);
20155714Skris		return 0;
20255714Skris	}
20355714Skris	sk_ASN1_TYPE_push (attrib->value.set,fname);
20455714Skris	attrib->set = 1;
20555714Skris	if (!bag->attrib && !(bag->attrib = sk_X509_ATTRIBUTE_new (NULL))) {
20655714Skris		PKCS12err(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI,
20755714Skris							ERR_R_MALLOC_FAILURE);
20855714Skris		return 0;
20955714Skris	}
21055714Skris	sk_X509_ATTRIBUTE_push (bag->attrib, attrib);
21155714Skris	return PKCS12_OK;
21255714Skris}
21355714Skris
21455714SkrisASN1_TYPE *PKCS12_get_attr_gen (STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid)
21555714Skris{
21655714Skris	X509_ATTRIBUTE *attrib;
21755714Skris	int i;
21855714Skris	if (!attrs) return NULL;
21955714Skris	for (i = 0; i < sk_X509_ATTRIBUTE_num (attrs); i++) {
22055714Skris		attrib = sk_X509_ATTRIBUTE_value (attrs, i);
22155714Skris		if (OBJ_obj2nid (attrib->object) == attr_nid) {
22255714Skris			if (sk_ASN1_TYPE_num (attrib->value.set))
22355714Skris			    return sk_ASN1_TYPE_value(attrib->value.set, 0);
22455714Skris			else return NULL;
22555714Skris		}
22655714Skris	}
22755714Skris	return NULL;
22855714Skris}
22955714Skris
23055714Skrischar *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag)
23155714Skris{
23255714Skris	ASN1_TYPE *atype;
23355714Skris	if (!(atype = PKCS12_get_attr(bag, NID_friendlyName))) return NULL;
23455714Skris	if (atype->type != V_ASN1_BMPSTRING) return NULL;
23555714Skris	return uni2asc(atype->value.bmpstring->data,
23655714Skris				 atype->value.bmpstring->length);
23755714Skris}
23855714Skris
239