os/ossrv/ssl/libcrypto/src/crypto/x509/x509_att.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* crypto/x509/x509_att.c */
sl@0
     2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
sl@0
     3
 * All rights reserved.
sl@0
     4
 *
sl@0
     5
 * This package is an SSL implementation written
sl@0
     6
 * by Eric Young (eay@cryptsoft.com).
sl@0
     7
 * The implementation was written so as to conform with Netscapes SSL.
sl@0
     8
 * 
sl@0
     9
 * This library is free for commercial and non-commercial use as long as
sl@0
    10
 * the following conditions are aheared to.  The following conditions
sl@0
    11
 * apply to all code found in this distribution, be it the RC4, RSA,
sl@0
    12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
sl@0
    13
 * included with this distribution is covered by the same copyright terms
sl@0
    14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
sl@0
    15
 * 
sl@0
    16
 * Copyright remains Eric Young's, and as such any Copyright notices in
sl@0
    17
 * the code are not to be removed.
sl@0
    18
 * If this package is used in a product, Eric Young should be given attribution
sl@0
    19
 * as the author of the parts of the library used.
sl@0
    20
 * This can be in the form of a textual message at program startup or
sl@0
    21
 * in documentation (online or textual) provided with the package.
sl@0
    22
 * 
sl@0
    23
 * Redistribution and use in source and binary forms, with or without
sl@0
    24
 * modification, are permitted provided that the following conditions
sl@0
    25
 * are met:
sl@0
    26
 * 1. Redistributions of source code must retain the copyright
sl@0
    27
 *    notice, this list of conditions and the following disclaimer.
sl@0
    28
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    29
 *    notice, this list of conditions and the following disclaimer in the
sl@0
    30
 *    documentation and/or other materials provided with the distribution.
sl@0
    31
 * 3. All advertising materials mentioning features or use of this software
sl@0
    32
 *    must display the following acknowledgement:
sl@0
    33
 *    "This product includes cryptographic software written by
sl@0
    34
 *     Eric Young (eay@cryptsoft.com)"
sl@0
    35
 *    The word 'cryptographic' can be left out if the rouines from the library
sl@0
    36
 *    being used are not cryptographic related :-).
sl@0
    37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
sl@0
    38
 *    the apps directory (application code) you must include an acknowledgement:
sl@0
    39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
sl@0
    40
 * 
sl@0
    41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
sl@0
    42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
sl@0
    44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
sl@0
    45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
sl@0
    46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
sl@0
    47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
sl@0
    49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
sl@0
    50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
sl@0
    51
 * SUCH DAMAGE.
sl@0
    52
 * 
sl@0
    53
 * The licence and distribution terms for any publically available version or
sl@0
    54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
sl@0
    55
 * copied and put under another distribution licence
sl@0
    56
 * [including the GNU Public Licence.]
sl@0
    57
 */
sl@0
    58
sl@0
    59
#include <stdio.h>
sl@0
    60
#include <openssl/stack.h>
sl@0
    61
#include "cryptlib.h"
sl@0
    62
#include <openssl/asn1.h>
sl@0
    63
#include <openssl/objects.h>
sl@0
    64
#include <openssl/evp.h>
sl@0
    65
#include <openssl/x509.h>
sl@0
    66
#include <openssl/x509v3.h>
sl@0
    67
sl@0
    68
EXPORT_C int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
sl@0
    69
{
sl@0
    70
	if (!x) return 0;
sl@0
    71
	return(sk_X509_ATTRIBUTE_num(x));
sl@0
    72
}
sl@0
    73
sl@0
    74
EXPORT_C int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
sl@0
    75
			  int lastpos)
sl@0
    76
{
sl@0
    77
	ASN1_OBJECT *obj;
sl@0
    78
sl@0
    79
	obj=OBJ_nid2obj(nid);
sl@0
    80
	if (obj == NULL) return(-2);
sl@0
    81
	return(X509at_get_attr_by_OBJ(x,obj,lastpos));
sl@0
    82
}
sl@0
    83
sl@0
    84
EXPORT_C int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj,
sl@0
    85
			  int lastpos)
sl@0
    86
{
sl@0
    87
	int n;
sl@0
    88
	X509_ATTRIBUTE *ex;
sl@0
    89
sl@0
    90
	if (sk == NULL) return(-1);
sl@0
    91
	lastpos++;
sl@0
    92
	if (lastpos < 0)
sl@0
    93
		lastpos=0;
sl@0
    94
	n=sk_X509_ATTRIBUTE_num(sk);
sl@0
    95
	for ( ; lastpos < n; lastpos++)
sl@0
    96
		{
sl@0
    97
		ex=sk_X509_ATTRIBUTE_value(sk,lastpos);
sl@0
    98
		if (OBJ_cmp(ex->object,obj) == 0)
sl@0
    99
			return(lastpos);
sl@0
   100
		}
sl@0
   101
	return(-1);
sl@0
   102
}
sl@0
   103
sl@0
   104
EXPORT_C X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc)
sl@0
   105
{
sl@0
   106
	if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
sl@0
   107
		return NULL;
sl@0
   108
	else
sl@0
   109
		return sk_X509_ATTRIBUTE_value(x,loc);
sl@0
   110
}
sl@0
   111
sl@0
   112
EXPORT_C X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc)
sl@0
   113
{
sl@0
   114
	X509_ATTRIBUTE *ret;
sl@0
   115
sl@0
   116
	if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
sl@0
   117
		return(NULL);
sl@0
   118
	ret=sk_X509_ATTRIBUTE_delete(x,loc);
sl@0
   119
	return(ret);
sl@0
   120
}
sl@0
   121
sl@0
   122
EXPORT_C STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
sl@0
   123
					 X509_ATTRIBUTE *attr)
sl@0
   124
{
sl@0
   125
	X509_ATTRIBUTE *new_attr=NULL;
sl@0
   126
	STACK_OF(X509_ATTRIBUTE) *sk=NULL;
sl@0
   127
sl@0
   128
	if (x == NULL)
sl@0
   129
		{
sl@0
   130
		X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_PASSED_NULL_PARAMETER);
sl@0
   131
		goto err2;
sl@0
   132
		} 
sl@0
   133
sl@0
   134
	if (*x == NULL)
sl@0
   135
		{
sl@0
   136
		if ((sk=sk_X509_ATTRIBUTE_new_null()) == NULL)
sl@0
   137
			goto err;
sl@0
   138
		}
sl@0
   139
	else
sl@0
   140
		sk= *x;
sl@0
   141
sl@0
   142
	if ((new_attr=X509_ATTRIBUTE_dup(attr)) == NULL)
sl@0
   143
		goto err2;
sl@0
   144
	if (!sk_X509_ATTRIBUTE_push(sk,new_attr))
sl@0
   145
		goto err;
sl@0
   146
	if (*x == NULL)
sl@0
   147
		*x=sk;
sl@0
   148
	return(sk);
sl@0
   149
err:
sl@0
   150
	X509err(X509_F_X509AT_ADD1_ATTR,ERR_R_MALLOC_FAILURE);
sl@0
   151
err2:
sl@0
   152
	if (new_attr != NULL) X509_ATTRIBUTE_free(new_attr);
sl@0
   153
	if (sk != NULL) sk_X509_ATTRIBUTE_free(sk);
sl@0
   154
	return(NULL);
sl@0
   155
}
sl@0
   156
sl@0
   157
EXPORT_C STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
sl@0
   158
			const ASN1_OBJECT *obj, int type,
sl@0
   159
			const unsigned char *bytes, int len)
sl@0
   160
{
sl@0
   161
	X509_ATTRIBUTE *attr;
sl@0
   162
	STACK_OF(X509_ATTRIBUTE) *ret;
sl@0
   163
	attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
sl@0
   164
	if(!attr) return 0;
sl@0
   165
	ret = X509at_add1_attr(x, attr);
sl@0
   166
	X509_ATTRIBUTE_free(attr);
sl@0
   167
	return ret;
sl@0
   168
}
sl@0
   169
sl@0
   170
EXPORT_C STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
sl@0
   171
			int nid, int type,
sl@0
   172
			const unsigned char *bytes, int len)
sl@0
   173
{
sl@0
   174
	X509_ATTRIBUTE *attr;
sl@0
   175
	STACK_OF(X509_ATTRIBUTE) *ret;
sl@0
   176
	attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
sl@0
   177
	if(!attr) return 0;
sl@0
   178
	ret = X509at_add1_attr(x, attr);
sl@0
   179
	X509_ATTRIBUTE_free(attr);
sl@0
   180
	return ret;
sl@0
   181
}
sl@0
   182
sl@0
   183
EXPORT_C STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
sl@0
   184
			const char *attrname, int type,
sl@0
   185
			const unsigned char *bytes, int len)
sl@0
   186
{
sl@0
   187
	X509_ATTRIBUTE *attr;
sl@0
   188
	STACK_OF(X509_ATTRIBUTE) *ret;
sl@0
   189
	attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
sl@0
   190
	if(!attr) return 0;
sl@0
   191
	ret = X509at_add1_attr(x, attr);
sl@0
   192
	X509_ATTRIBUTE_free(attr);
sl@0
   193
	return ret;
sl@0
   194
}
sl@0
   195
sl@0
   196
EXPORT_C X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
sl@0
   197
	     int atrtype, const void *data, int len)
sl@0
   198
{
sl@0
   199
	ASN1_OBJECT *obj;
sl@0
   200
	X509_ATTRIBUTE *ret;
sl@0
   201
sl@0
   202
	obj=OBJ_nid2obj(nid);
sl@0
   203
	if (obj == NULL)
sl@0
   204
		{
sl@0
   205
		X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID,X509_R_UNKNOWN_NID);
sl@0
   206
		return(NULL);
sl@0
   207
		}
sl@0
   208
	ret=X509_ATTRIBUTE_create_by_OBJ(attr,obj,atrtype,data,len);
sl@0
   209
	if (ret == NULL) ASN1_OBJECT_free(obj);
sl@0
   210
	return(ret);
sl@0
   211
}
sl@0
   212
sl@0
   213
EXPORT_C X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
sl@0
   214
	     const ASN1_OBJECT *obj, int atrtype, const void *data, int len)
sl@0
   215
{
sl@0
   216
	X509_ATTRIBUTE *ret;
sl@0
   217
sl@0
   218
	if ((attr == NULL) || (*attr == NULL))
sl@0
   219
		{
sl@0
   220
		if ((ret=X509_ATTRIBUTE_new()) == NULL)
sl@0
   221
			{
sl@0
   222
			X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ,ERR_R_MALLOC_FAILURE);
sl@0
   223
			return(NULL);
sl@0
   224
			}
sl@0
   225
		}
sl@0
   226
	else
sl@0
   227
		ret= *attr;
sl@0
   228
sl@0
   229
	if (!X509_ATTRIBUTE_set1_object(ret,obj))
sl@0
   230
		goto err;
sl@0
   231
	if (!X509_ATTRIBUTE_set1_data(ret,atrtype,data,len))
sl@0
   232
		goto err;
sl@0
   233
	
sl@0
   234
	if ((attr != NULL) && (*attr == NULL)) *attr=ret;
sl@0
   235
	return(ret);
sl@0
   236
err:
sl@0
   237
	if ((attr == NULL) || (ret != *attr))
sl@0
   238
		X509_ATTRIBUTE_free(ret);
sl@0
   239
	return(NULL);
sl@0
   240
}
sl@0
   241
sl@0
   242
EXPORT_C X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
sl@0
   243
		const char *atrname, int type, const unsigned char *bytes, int len)
sl@0
   244
	{
sl@0
   245
	ASN1_OBJECT *obj;
sl@0
   246
	X509_ATTRIBUTE *nattr;
sl@0
   247
sl@0
   248
	obj=OBJ_txt2obj(atrname, 0);
sl@0
   249
	if (obj == NULL)
sl@0
   250
		{
sl@0
   251
		X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT,
sl@0
   252
						X509_R_INVALID_FIELD_NAME);
sl@0
   253
		ERR_add_error_data(2, "name=", atrname);
sl@0
   254
		return(NULL);
sl@0
   255
		}
sl@0
   256
	nattr = X509_ATTRIBUTE_create_by_OBJ(attr,obj,type,bytes,len);
sl@0
   257
	ASN1_OBJECT_free(obj);
sl@0
   258
	return nattr;
sl@0
   259
	}
sl@0
   260
sl@0
   261
EXPORT_C int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
sl@0
   262
{
sl@0
   263
	if ((attr == NULL) || (obj == NULL))
sl@0
   264
		return(0);
sl@0
   265
	ASN1_OBJECT_free(attr->object);
sl@0
   266
	attr->object=OBJ_dup(obj);
sl@0
   267
	return(1);
sl@0
   268
}
sl@0
   269
sl@0
   270
EXPORT_C int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len)
sl@0
   271
{
sl@0
   272
	ASN1_TYPE *ttmp;
sl@0
   273
	ASN1_STRING *stmp;
sl@0
   274
	int atype;
sl@0
   275
	if (!attr) return 0;
sl@0
   276
	if(attrtype & MBSTRING_FLAG) {
sl@0
   277
		stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
sl@0
   278
						OBJ_obj2nid(attr->object));
sl@0
   279
		if(!stmp) {
sl@0
   280
			X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB);
sl@0
   281
			return 0;
sl@0
   282
		}
sl@0
   283
		atype = stmp->type;
sl@0
   284
	} else {
sl@0
   285
		if(!(stmp = ASN1_STRING_type_new(attrtype))) goto err;
sl@0
   286
		if(!ASN1_STRING_set(stmp, data, len)) goto err;
sl@0
   287
		atype = attrtype;
sl@0
   288
	}
sl@0
   289
	if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
sl@0
   290
	if(!(ttmp = ASN1_TYPE_new())) goto err;
sl@0
   291
	if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err;
sl@0
   292
	attr->single = 0;
sl@0
   293
	ASN1_TYPE_set(ttmp, atype, stmp);
sl@0
   294
	return 1;
sl@0
   295
	err:
sl@0
   296
	X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE);
sl@0
   297
	return 0;
sl@0
   298
}
sl@0
   299
sl@0
   300
EXPORT_C int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr)
sl@0
   301
{
sl@0
   302
	if(!attr->single) return sk_ASN1_TYPE_num(attr->value.set);
sl@0
   303
	if(attr->value.single) return 1;
sl@0
   304
	return 0;
sl@0
   305
}
sl@0
   306
sl@0
   307
EXPORT_C ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
sl@0
   308
{
sl@0
   309
	if (attr == NULL) return(NULL);
sl@0
   310
	return(attr->object);
sl@0
   311
}
sl@0
   312
sl@0
   313
EXPORT_C void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
sl@0
   314
					int atrtype, void *data)
sl@0
   315
{
sl@0
   316
	ASN1_TYPE *ttmp;
sl@0
   317
	ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
sl@0
   318
	if(!ttmp) return NULL;
sl@0
   319
	if(atrtype != ASN1_TYPE_get(ttmp)){
sl@0
   320
		X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE);
sl@0
   321
		return NULL;
sl@0
   322
	}
sl@0
   323
	return ttmp->value.ptr;
sl@0
   324
}
sl@0
   325
sl@0
   326
EXPORT_C ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
sl@0
   327
{
sl@0
   328
	if (attr == NULL) return(NULL);
sl@0
   329
	if(idx >= X509_ATTRIBUTE_count(attr)) return NULL;
sl@0
   330
	if(!attr->single) return sk_ASN1_TYPE_value(attr->value.set, idx);
sl@0
   331
	else return attr->value.single;
sl@0
   332
}