os/ossrv/ssl/libcrypto/src/crypto/x509v3/v3_pci.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */
     2 /* Contributed to the OpenSSL Project 2004
     3  * by Richard Levitte (richard@levitte.org)
     4  */
     5 /* Copyright (c) 2004 Kungliga Tekniska Högskolan
     6  * (Royal Institute of Technology, Stockholm, Sweden).
     7  * All rights reserved.
     8  *
     9  * Redistribution and use in source and binary forms, with or without
    10  * modification, are permitted provided that the following conditions
    11  * are met:
    12  *
    13  * 1. Redistributions of source code must retain the above copyright
    14  *    notice, this list of conditions and the following disclaimer.
    15  *
    16  * 2. Redistributions in binary form must reproduce the above copyright
    17  *    notice, this list of conditions and the following disclaimer in the
    18  *    documentation and/or other materials provided with the distribution.
    19  *
    20  * 3. Neither the name of the Institute nor the names of its contributors
    21  *    may be used to endorse or promote products derived from this software
    22  *    without specific prior written permission.
    23  *
    24  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
    25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
    28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    34  * SUCH DAMAGE.
    35  */
    36 /*
    37  © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
    38  */
    39 #include <stdio.h>
    40 #include "cryptlib.h"
    41 #include <openssl/conf.h>
    42 #include <openssl/x509v3.h>
    43 #if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
    44 #include "libcrypto_wsd_macros.h"
    45 #include "libcrypto_wsd.h"
    46 #endif
    47 
    48 
    49 static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
    50 	BIO *out, int indent);
    51 static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
    52 	X509V3_CTX *ctx, char *str);
    53 #ifndef EMULATOR
    54 X509V3_EXT_METHOD v3_pci =
    55 	{ NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
    56 	  0,0,0,0,
    57 	  0,0,
    58 	  NULL, NULL,
    59 	  (X509V3_EXT_I2R)i2r_pci,
    60 	  (X509V3_EXT_R2I)r2i_pci,
    61 	  NULL,
    62 	};
    63 #else
    64 const X509V3_EXT_METHOD v3_pci =
    65 	{ NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
    66 	  0,0,0,0,
    67 	  0,0,
    68 	  NULL, NULL,
    69 	  (X509V3_EXT_I2R)i2r_pci,
    70 	  (X509V3_EXT_R2I)r2i_pci,
    71 	  NULL,
    72 	};
    73 #endif
    74 static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci,
    75 	BIO *out, int indent)
    76 	{
    77 	BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
    78 	if (pci->pcPathLengthConstraint)
    79 	  i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
    80 	else
    81 	  BIO_printf(out, "infinite");
    82 	BIO_puts(out, "\n");
    83 	BIO_printf(out, "%*sPolicy Language: ", indent, "");
    84 	i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
    85 	BIO_puts(out, "\n");
    86 	if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
    87 	  BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
    88 		     pci->proxyPolicy->policy->data);
    89 	return 1;
    90 	}
    91 
    92 static int process_pci_value(CONF_VALUE *val,
    93 	ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
    94 	ASN1_OCTET_STRING **policy)
    95 	{
    96 	int free_policy = 0;
    97 
    98 	if (strcmp(val->name, "language") == 0)
    99 		{
   100 		if (*language)
   101 			{
   102 			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED);
   103 			X509V3_conf_err(val);
   104 			return 0;
   105 			}
   106 		if (!(*language = OBJ_txt2obj(val->value, 0)))
   107 			{
   108 			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INVALID_OBJECT_IDENTIFIER);
   109 			X509V3_conf_err(val);
   110 			return 0;
   111 			}
   112 		}
   113 	else if (strcmp(val->name, "pathlen") == 0)
   114 		{
   115 		if (*pathlen)
   116 			{
   117 			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED);
   118 			X509V3_conf_err(val);
   119 			return 0;
   120 			}
   121 		if (!X509V3_get_value_int(val, pathlen))
   122 			{
   123 			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_POLICY_PATH_LENGTH);
   124 			X509V3_conf_err(val);
   125 			return 0;
   126 			}
   127 		}
   128 	else if (strcmp(val->name, "policy") == 0)
   129 		{
   130 		unsigned char *tmp_data = NULL;
   131 		long val_len;
   132 		if (!*policy)
   133 			{
   134 			*policy = ASN1_OCTET_STRING_new();
   135 			if (!*policy)
   136 				{
   137 				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
   138 				X509V3_conf_err(val);
   139 				return 0;
   140 				}
   141 			free_policy = 1;
   142 			}
   143 		if (strncmp(val->value, "hex:", 4) == 0)
   144 			{
   145 			unsigned char *tmp_data2 =
   146 				string_to_hex(val->value + 4, &val_len);
   147 
   148 			if (!tmp_data2) goto err;
   149 
   150 			tmp_data = OPENSSL_realloc((*policy)->data,
   151 				(*policy)->length + val_len + 1);
   152 			if (tmp_data)
   153 				{
   154 				(*policy)->data = tmp_data;
   155 				memcpy(&(*policy)->data[(*policy)->length],
   156 					tmp_data2, val_len);
   157 				(*policy)->length += val_len;
   158 				(*policy)->data[(*policy)->length] = '\0';
   159 				}
   160 			}
   161 		else if (strncmp(val->value, "file:", 5) == 0)
   162 			{
   163 #ifndef SYMBIAN			
   164 			unsigned char buf[2048];
   165 #else
   166       unsigned char buf[1024];
   167 #endif			
   168 			int n;
   169 			BIO *b = BIO_new_file(val->value + 5, "r");
   170 			if (!b)
   171 				{
   172 				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
   173 				X509V3_conf_err(val);
   174 				goto err;
   175 				}
   176 			while((n = BIO_read(b, buf, sizeof(buf))) > 0
   177 				|| (n == 0 && BIO_should_retry(b)))
   178 				{
   179 				if (!n) continue;
   180 
   181 				tmp_data = OPENSSL_realloc((*policy)->data,
   182 					(*policy)->length + n + 1);
   183 
   184 				if (!tmp_data)
   185 					break;
   186 
   187 				(*policy)->data = tmp_data;
   188 				memcpy(&(*policy)->data[(*policy)->length],
   189 					buf, n);
   190 				(*policy)->length += n;
   191 				(*policy)->data[(*policy)->length] = '\0';
   192 				}
   193 
   194 			if (n < 0)
   195 				{
   196 				X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_BIO_LIB);
   197 				X509V3_conf_err(val);
   198 				goto err;
   199 				}
   200 			}
   201 		else if (strncmp(val->value, "text:", 5) == 0)
   202 			{
   203 			val_len = strlen(val->value + 5);
   204 			tmp_data = OPENSSL_realloc((*policy)->data,
   205 				(*policy)->length + val_len + 1);
   206 			if (tmp_data)
   207 				{
   208 				(*policy)->data = tmp_data;
   209 				memcpy(&(*policy)->data[(*policy)->length],
   210 					val->value + 5, val_len);
   211 				(*policy)->length += val_len;
   212 				(*policy)->data[(*policy)->length] = '\0';
   213 				}
   214 			}
   215 		else
   216 			{
   217 			X509V3err(X509V3_F_PROCESS_PCI_VALUE,X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
   218 			X509V3_conf_err(val);
   219 			goto err;
   220 			}
   221 		if (!tmp_data)
   222 			{
   223 			X509V3err(X509V3_F_PROCESS_PCI_VALUE,ERR_R_MALLOC_FAILURE);
   224 			X509V3_conf_err(val);
   225 			goto err;
   226 			}
   227 		}
   228 	return 1;
   229 err:
   230 	if (free_policy)
   231 		{
   232 		ASN1_OCTET_STRING_free(*policy);
   233 		*policy = NULL;
   234 		}
   235 	return 0;
   236 	}
   237 
   238 static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
   239 	X509V3_CTX *ctx, char *value)
   240 	{
   241 	PROXY_CERT_INFO_EXTENSION *pci = NULL;
   242 	STACK_OF(CONF_VALUE) *vals;
   243 	ASN1_OBJECT *language = NULL;
   244 	ASN1_INTEGER *pathlen = NULL;
   245 	ASN1_OCTET_STRING *policy = NULL;
   246 	int i, j;
   247 
   248 	vals = X509V3_parse_list(value);
   249 	for (i = 0; i < sk_CONF_VALUE_num(vals); i++)
   250 		{
   251 		CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
   252 		if (!cnf->name || (*cnf->name != '@' && !cnf->value))
   253 			{
   254 			X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_PROXY_POLICY_SETTING);
   255 			X509V3_conf_err(cnf);
   256 			goto err;
   257 			}
   258 		if (*cnf->name == '@')
   259 			{
   260 			STACK_OF(CONF_VALUE) *sect;
   261 			int success_p = 1;
   262 
   263 			sect = X509V3_get_section(ctx, cnf->name + 1);
   264 			if (!sect)
   265 				{
   266 				X509V3err(X509V3_F_R2I_PCI,X509V3_R_INVALID_SECTION);
   267 				X509V3_conf_err(cnf);
   268 				goto err;
   269 				}
   270 			for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++)
   271 				{
   272 				success_p =
   273 					process_pci_value(sk_CONF_VALUE_value(sect, j),
   274 						&language, &pathlen, &policy);
   275 				}
   276 			X509V3_section_free(ctx, sect);
   277 			if (!success_p)
   278 				goto err;
   279 			}
   280 		else
   281 			{
   282 			if (!process_pci_value(cnf,
   283 					&language, &pathlen, &policy))
   284 				{
   285 				X509V3_conf_err(cnf);
   286 				goto err;
   287 				}
   288 			}
   289 		}
   290 
   291 	/* Language is mandatory */
   292 	if (!language)
   293 		{
   294 		X509V3err(X509V3_F_R2I_PCI,X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
   295 		goto err;
   296 		}
   297 	i = OBJ_obj2nid(language);
   298 	if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy)
   299 		{
   300 		X509V3err(X509V3_F_R2I_PCI,X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
   301 		goto err;
   302 		}
   303 
   304 	pci = PROXY_CERT_INFO_EXTENSION_new();
   305 	if (!pci)
   306 		{
   307 		X509V3err(X509V3_F_R2I_PCI,ERR_R_MALLOC_FAILURE);
   308 		goto err;
   309 		}
   310 
   311 	pci->proxyPolicy->policyLanguage = language; language = NULL;
   312 	pci->proxyPolicy->policy = policy; policy = NULL;
   313 	pci->pcPathLengthConstraint = pathlen; pathlen = NULL;
   314 	goto end;
   315 err:
   316 	if (language) { ASN1_OBJECT_free(language); language = NULL; }
   317 	if (pathlen) { ASN1_INTEGER_free(pathlen); pathlen = NULL; }
   318 	if (policy) { ASN1_OCTET_STRING_free(policy); policy = NULL; }
   319 	if (pci) { PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; }
   320 end:
   321 	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
   322 	return pci;
   323 	}