annotate usr/src/cmd/agents/snmp/snmplib/asn1.c @ 0:c9caec207d52 b86

Initial porting based on b86
author Koji Uno <koji.uno@sun.com>
date Tue, 02 Jun 2009 18:56:50 +0900
parents
children 1a15d5aaf794
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
1 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
2 * CDDL HEADER START
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
3 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
4 * The contents of this file are subject to the terms of the
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
5 * Common Development and Distribution License, Version 1.0 only
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
6 * (the "License"). You may not use this file except in compliance
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
7 * with the License.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
8 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
10 * or http://www.opensolaris.org/os/licensing.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
11 * See the License for the specific language governing permissions
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
12 * and limitations under the License.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
13 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
14 * When distributing Covered Code, include this CDDL HEADER in each
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
16 * If applicable, add the following below this CDDL HEADER, with the
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
17 * fields enclosed by brackets "[]" replaced with your own identifying
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
18 * information: Portions Copyright [yyyy] [name of copyright owner]
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
19 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
20 * CDDL HEADER END
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
21 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
22 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
23 * Copyright 2001,2002 Sun Microsystems, Inc. All rights reserved.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
24 * Use is subject to license terms.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
25 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
26
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
27 #pragma ident "@(#)asn1.c 1.10 05/06/12 SMI"
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
28
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
29 #include <string.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
30 #include <stdio.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
31 #include <sys/types.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
32 #include <netinet/in.h>
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
33 #include "snmp_msg.h"
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
34 #include "asn1.h"
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
35
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
36
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
37 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
38 * asn_parse_int - pulls a int32_t out of an ASN int type.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
39 * On entry, datalength is input as the number of valid bytes following
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
40 * "data". On exit, it is returned as the number of valid bytes
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
41 * following the end of this object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
42 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
43 * Returns a pointer to the first byte past the end
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
44 * of this object (i.e. the start of the next object).
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
45 * Returns NULL on any error.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
46 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
47 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
48 asn_parse_int(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
49 u_char *data, /* IN - pointer to start of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
50 uint32_t *datalength,/* IN/OUT - number of valid bytes left in buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
51 u_char *type, /* OUT - asn type of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
52 int32_t *intp, /* IN/OUT - pointer to start of output buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
53 uint32_t intsize, /* IN - size of output buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
54 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
55 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
56 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
57 * ASN.1 integer ::= 0x02 asnlength byte {byte}*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
58 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
59 u_char *bufp = data;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
60 uint32_t asn_length = 0;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
61 int32_t value = 0;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
62
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
63
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
64 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
65
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
66 if (intsize != sizeof (int32_t)){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
67 (void)sprintf(error_label, ERR_MSG_NOT_LONG);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
68 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
69 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
70 *type = *bufp++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
71 bufp = asn_parse_length(bufp, &asn_length, error_label);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
72 if (bufp == NULL){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
73 (void)sprintf(error_label, ERR_MSG_BAD_LENGTH);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
74 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
75 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
76 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
77 if (asn_length + (uint32_t)(bufp - data) > *datalength){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
78 (void)sprintf(error_label, ERR_MSG_OVERFLOW);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
79 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
80 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
81 if (asn_length > intsize){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
82 (void)sprintf(error_label, ERR_MSG_DONT_SUPPORT_LARGE_INT);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
83 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
84 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
85 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
86 *datalength -= asn_length + (uint32_t)(bufp - data);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
87 if (*bufp & 0x80)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
88 value = -1; /* integer is negative */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
89 while(asn_length--)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
90 value = (value << 8) | *bufp++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
91 *intp = value;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
92 return bufp;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
93 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
94
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
95 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
96 * asn_parse_unsigned_int - pulls an unsigned int32_t out of an ASN int type.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
97 * On entry, datalength is input as the number of valid bytes following
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
98 * "data". On exit, it is returned as the number of valid bytes
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
99 * following the end of this object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
100 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
101 * Returns a pointer to the first byte past the end
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
102 * of this object (i.e. the start of the next object).
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
103 * Returns NULL on any error.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
104 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
105 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
106 asn_parse_unsigned_int(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
107 u_char *data, /* IN - pointer to start of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
108 uint32_t * datalength,/* IN/OUT - number of valid bytes left in buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
109 u_char *type, /* OUT - asn type of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
110 int32_t *intp, /* IN/OUT - pointer to start of output buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
111 uint32_t intsize, /* IN - size of output buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
112 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
113 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
114 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
115 * ASN.1 integer ::= 0x02 asnlength byte {byte}*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
116 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
117 u_char *bufp = data;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
118 uint32_t asn_length;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
119 uint32_t value = 0;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
120
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
121 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
122
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
123 if (intsize != sizeof (int32_t)){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
124 (void)sprintf(error_label, ERR_MSG_NOT_LONG);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
125 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
126 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
127 *type = *bufp++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
128 bufp = asn_parse_length(bufp, &asn_length, error_label);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
129 if (bufp == NULL){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
130 (void)sprintf(error_label, ERR_MSG_BAD_LENGTH);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
131 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
132 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
133 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
134 if (asn_length + (uint32_t)(bufp - data) > *datalength){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
135 (void)sprintf(error_label, ERR_MSG_OVERFLOW);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
136 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
137 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
138 if ((asn_length > (intsize + 1)) ||
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
139 ((asn_length == intsize + 1) && *bufp != 0x00)){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
140 (void)sprintf(error_label, ERR_MSG_DONT_SUPPORT_LARGE_INT);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
141 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
142 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
143 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
144 *datalength -= asn_length + (uint32_t)(bufp - data);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
145 if (*bufp & 0x80)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
146 value = -1U; /* integer is negative */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
147 while(asn_length--)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
148 value = (value << 8) | *bufp++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
149 *intp = value;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
150 return bufp;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
151 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
152
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
153
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
154 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
155 * asn_build_int - builds an ASN object containing an integer.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
156 * On entry, datalength is input as the number of valid bytes following
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
157 * "data". On exit, it is returned as the number of valid bytes
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
158 * following the end of this object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
159 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
160 * Returns a pointer to the first byte past the end
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
161 * of this object (i.e. the start of the next object).
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
162 * Returns NULL on any error.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
163 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
164 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
165 asn_build_int(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
166 u_char *data, /* IN - pointer to start of output buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
167 uint32_t * datalength,/* IN/OUT - number of valid bytes left in buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
168 u_char type, /* IN - asn type of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
169 int32_t *intp, /* IN - pointer to start of integer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
170 uint32_t intsize, /* IN - size of *intp */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
171 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
172 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
173 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
174 * ASN.1 integer ::= 0x02 asnlength byte {byte}*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
175 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
176
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
177 int32_t integer;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
178 uint32_t mask;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
179
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
180 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
181
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
182 if (intsize != sizeof (int32_t))
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
183 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
184 integer = *intp;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
185 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
186 * Truncate "unnecessary" bytes off of the most significant end of this 2's
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
187 * complement integer. There should be no sequence of 9 consecutive 1's or
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
188 * 0's at the most significant end of the integer.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
189 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
190 mask = ((uint32_t) 0x1FF) << ((8 * (sizeof(int32_t) - 1)) - 1);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
191
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
192 /* mask is 0xFF800000 on a big-endian machine */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
193 while((((integer & mask) == 0) || ((integer & mask) == mask)) && intsize > 1){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
194 intsize--;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
195 integer <<= 8;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
196 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
197 data = asn_build_header(data, datalength, type, intsize, error_label);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
198 if (data == NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
199 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
200 if (*datalength < intsize)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
201 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
202 *datalength -= intsize;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
203
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
204 mask = ((uint32_t) 0xFF) << (8 * (sizeof(int32_t) - 1));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
205
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
206 /* mask is 0xFF000000 on a big-endian machine */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
207 while(intsize--){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
208 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
209 *data++ = (u_char)((integer & mask) >> (8 * (sizeof(int32_t) - 1)));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
210 integer <<= 8;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
211 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
212 return data;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
213 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
214
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
215 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
216 * asn_build_unsigned_int - builds an ASN object containing an integer.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
217 * On entry, datalength is input as the number of valid bytes following
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
218 * "data". On exit, it is returned as the number of valid bytes
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
219 * following the end of this object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
220 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
221 * Returns a pointer to the first byte past the end
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
222 * of this object (i.e. the start of the next object).
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
223 * Returns NULL on any error.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
224 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
225 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
226 asn_build_unsigned_int(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
227 u_char *data, /* IN - pointer to start of output buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
228 uint32_t *datalength,/* IN/OUT - number of valid bytes left in buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
229 u_char type, /* IN - asn type of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
230 int32_t *intp, /* IN - pointer to start of int32_t integer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
231 uint32_t intsize, /* IN - size of *intp */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
232 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
233 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
234 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
235 * ASN.1 integer ::= 0x02 asnlength byte {byte}*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
236 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
237
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
238 uint32_t integer;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
239 uint32_t mask;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
240 int add_null_byte = 0;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
241
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
242 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
243
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
244 if (intsize != sizeof (int32_t))
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
245 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
246 integer = *intp;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
247 mask = ((uint32_t) 0xFF) << (8 * (sizeof(int32_t) - 1));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
248 /* mask is 0xFF000000 on a big-endian machine */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
249 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
250 if ((u_char)((integer & mask) >> (8 * (sizeof(int32_t) - 1))) & 0x80){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
251 /* if MSB is set */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
252 add_null_byte = 1;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
253 intsize++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
254 } else {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
255 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
256 * Truncate "unnecessary" bytes off of the most significant end of this 2's complement integer.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
257 * There should be no sequence of 9 consecutive 1's or 0's at the most significant end of the
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
258 * integer.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
259 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
260 mask = ((uint32_t) 0x1FF) << ((8 * (sizeof(int32_t) - 1)) - 1);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
261 /* mask is 0xFF800000 on a big-endian machine */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
262 while(((integer & mask) == 0) && intsize > 1){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
263 intsize--;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
264 integer <<= 8;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
265 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
266 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
267 data = asn_build_header(data, datalength, type, intsize, error_label);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
268 if (data == NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
269 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
270 if (*datalength < intsize)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
271 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
272 *datalength -= intsize;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
273 if (add_null_byte == 1){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
274 *data++ = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
275 intsize--;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
276 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
277 mask = ((uint32_t) 0xFF) << (8 * (sizeof(int32_t) - 1));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
278 /* mask is 0xFF000000 on a big-endian machine */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
279 while(intsize--){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
280 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
281 *data++ = (u_char)((integer & mask) >> (8 * (sizeof(int32_t) - 1)));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
282 integer <<= 8;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
283 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
284 return data;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
285 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
286
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
287
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
288 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
289 * asn_parse_string - pulls an octet string out of an ASN octet string type.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
290 * On entry, datalength is input as the number of valid bytes following
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
291 * "data". On exit, it is returned as the number of valid bytes
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
292 * following the beginning of the next object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
293 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
294 * "string" is filled with the octet string.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
295 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
296 * Returns a pointer to the first byte past the end
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
297 * of this object (i.e. the start of the next object).
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
298 * Returns NULL on any error.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
299 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
300 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
301 asn_parse_string(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
302 u_char *data, /* IN - pointer to start of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
303 uint32_t *datalength, /* IN/OUT - number of valid bytes left in buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
304 u_char *type, /* OUT - asn type of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
305 u_char *string, /* IN/OUT - pointer to start of output buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
306 uint32_t *strlength, /* IN/OUT - size of output buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
307 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
308 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
309 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
310 * ASN.1 octet string ::= primstring | cmpdstring
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
311 * primstring ::= 0x04 asnlength byte {byte}*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
312 * cmpdstring ::= 0x24 asnlength string {string}*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
313 * This doesn't yet support the compound string.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
314 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
315 u_char *bufp = data;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
316 uint32_t asn_length = 0;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
317
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
318
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
319 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
320
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
321 *type = *bufp++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
322 bufp = asn_parse_length(bufp, &asn_length, error_label);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
323 if (bufp == NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
324 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
325 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
326 if (asn_length + (uint32_t)(bufp - data) > *datalength){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
327 (void)sprintf(error_label, ERR_MSG_OVERFLOW);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
328 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
329 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
330 if (asn_length > *strlength){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
331 (void)sprintf(error_label, ERR_MSG_DONT_SUPPORT_LARGE_STR);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
332 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
333 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
334 memcpy(string, bufp, asn_length);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
335 *strlength = asn_length;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
336 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
337 *datalength -= asn_length + (uint32_t)(bufp - data);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
338 return bufp + asn_length;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
339 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
340
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
341
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
342 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
343 * asn_build_string - Builds an ASN octet string object containing the input string.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
344 * On entry, datalength is input as the number of valid bytes following
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
345 * "data". On exit, it is returned as the number of valid bytes
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
346 * following the beginning of the next object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
347 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
348 * Returns a pointer to the first byte past the end
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
349 * of this object (i.e. the start of the next object).
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
350 * Returns NULL on any error.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
351 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
352 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
353 asn_build_string(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
354 u_char *data, /* IN - pointer to start of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
355 uint32_t *datalength, /* IN/OUT - number of valid bytes left in buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
356 u_char type, /* IN - ASN type of string */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
357 u_char *string, /* IN - pointer to start of input buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
358 uint32_t strlength, /* IN - size of input buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
359 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
360 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
361 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
362 * ASN.1 octet string ::= primstring | cmpdstring
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
363 * primstring ::= 0x04 asnlength byte {byte}*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
364 * cmpdstring ::= 0x24 asnlength string {string}*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
365 * This code will never send a compound string.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
366 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
367
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
368 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
369
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
370 data = asn_build_header(data, datalength, type, strlength, error_label);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
371 if (data == NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
372 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
373 if (*datalength < strlength)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
374 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
375 memcpy(data, string, strlength);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
376 *datalength -= strlength;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
377 return data + (intptr_t)strlength;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
378 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
379
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
380
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
381 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
382 * asn_parse_header - interprets the ID and length of the current object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
383 * On entry, datalength is input as the number of valid bytes following
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
384 * "data". On exit, it is returned as the number of valid bytes
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
385 * in this object following the id and length.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
386 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
387 * Returns a pointer to the first byte of the contents of this object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
388 * Returns NULL on any error.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
389 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
390 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
391 asn_parse_header(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
392 u_char *data, /* IN - pointer to start of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
393 uint32_t * datalength,/* IN/OUT - number of valid bytes left in buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
394 u_char *type, /* OUT - ASN type of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
395 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
396 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
397 u_char *bufp = data;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
398 uint32_t header_len;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
399 uint32_t asn_length = 0;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
400
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
401 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
402
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
403 /* this only works on data types < 30, i.e. no extension octets */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
404 if (IS_EXTENSION_ID(*bufp)){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
405 (void)sprintf(error_label, ERR_MSG_CANT_PROCESS_LONG_ID);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
406 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
407 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
408 *type = *bufp;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
409 bufp = asn_parse_length(bufp + 1, &asn_length, error_label);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
410 if (bufp == NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
411 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
412
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
413 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
414 header_len = (uint32_t)(bufp - data);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
415 if (header_len + asn_length > *datalength){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
416 (void)sprintf(error_label, ERR_MSG_ASN_LEN_TOO_LONG);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
417 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
418 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
419 *datalength = asn_length;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
420 return bufp;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
421 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
422
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
423 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
424 * asn_build_header - builds an ASN header for an object with the ID and
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
425 * length specified.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
426 * On entry, datalength is input as the number of valid bytes following
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
427 * "data". On exit, it is returned as the number of valid bytes
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
428 * in this object following the id and length.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
429 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
430 * This only works on data types < 30, i.e. no extension octets.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
431 * The maximum length is 0xFFFF;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
432 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
433 * Returns a pointer to the first byte of the contents of this object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
434 * Returns NULL on any error.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
435 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
436 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
437 asn_build_header(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
438 u_char *data, /* IN - pointer to start of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
439 uint32_t *datalength,/* IN/OUT - number of valid bytes left in buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
440 u_char type, /* IN - ASN type of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
441 uint32_t length, /* IN - length of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
442 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
443 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
444 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
445
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
446 if (*datalength == 0)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
447 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
448 *data++ = type;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
449 (*datalength)--;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
450 return asn_build_length(data, datalength, length, error_label);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
451
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
452 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
453
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
454 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
455 * asn_parse_length - interprets the length of the current object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
456 * On exit, length contains the value of this length field.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
457 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
458 * Returns a pointer to the first byte after this length
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
459 * field (aka: the start of the data field).
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
460 * Returns NULL on any error.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
461 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
462 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
463 asn_parse_length(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
464 u_char *data, /* IN - pointer to start of length field */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
465 uint32_t *length, /* OUT - value of length field */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
466 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
467 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
468 u_char lengthbyte = *data;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
469
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
470 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
471
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
472 if (lengthbyte & ASN_LONG_LEN){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
473 lengthbyte &= ~ASN_LONG_LEN; /* turn MSb off */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
474 if (lengthbyte == 0){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
475 (void)sprintf(error_label, ERR_MSG_DONT_SUPPORT_INDEF_LEN);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
476 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
477 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
478 if (lengthbyte > sizeof(int32_t)){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
479 (void)sprintf(error_label, ERR_MSG_DONT_SUPPORT_SUCH_LEN);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
480 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
481 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
482 memcpy(length, data + 1, (int)lengthbyte);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
483 *length = ntohl(*length);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
484 *length >>= (8 * ((sizeof *length) - lengthbyte));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
485 return data + lengthbyte + 1;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
486 } else { /* short asnlength */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
487 *length = (int32_t)lengthbyte;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
488 return data + 1;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
489 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
490 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
491
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
492 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
493 asn_build_length(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
494 u_char *data, /* IN - pointer to start of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
495 uint32_t *datalength, /* IN/OUT - number of valid bytes left in buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
496 uint32_t length, /* IN - length of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
497 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
498 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
499 u_char *start_data = data;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
500
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
501 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
502
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
503 /* no indefinite lengths sent */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
504 if (length < 0x80){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
505 if (*datalength < 1)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
506 goto errout;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
507 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
508 *data++ = (u_char)length;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
509 } else if (length <= 0xFF){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
510 if (*datalength < 2)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
511 goto errout;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
512 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
513 *data++ = (u_char)(0x01 | ASN_LONG_LEN);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
514 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
515 *data++ = (u_char)length;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
516 } else { /* 0xFF < length <= 0xFFFF */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
517 if (*datalength < 3)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
518 goto errout;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
519 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
520 *data++ = (u_char)(0x02 | ASN_LONG_LEN);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
521 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
522 *data++ = (u_char)((length >> 8) & 0xFF);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
523 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
524 *data++ = (u_char)(length & 0xFF);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
525 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
526 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
527 *datalength -= (uint32_t)(data - start_data);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
528 return data;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
529
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
530 errout:
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
531 (void)sprintf(error_label, ERR_MSG_BUILD_LENGTH);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
532 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
533 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
534
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
535 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
536 * asn_parse_objid - pulls an object indentifier out of an ASN object identifier type.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
537 * On entry, datalength is input as the number of valid bytes following
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
538 * "data". On exit, it is returned as the number of valid bytes
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
539 * following the beginning of the next object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
540 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
541 * "objid" is filled with the object identifier.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
542 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
543 * Returns a pointer to the first byte past the end
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
544 * of this object (i.e. the start of the next object).
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
545 * Returns NULL on any error.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
546 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
547 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
548 asn_parse_objid(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
549 u_char *data, /* IN - pointer to start of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
550 uint32_t *datalength, /* IN/OUT - number of valid bytes left in buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
551 u_char *type, /* OUT - ASN type of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
552 Subid *objid, /* IN/OUT - pointer to start of output buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
553 int32_t *objidlength, /* IN/OUT - number of sub-id's in objid */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
554 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
555 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
556 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
557 * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
558 * subidentifier ::= {leadingbyte}* lastbyte
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
559 * leadingbyte ::= 1 7bitvalue
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
560 * lastbyte ::= 0 7bitvalue
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
561 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
562 u_char *bufp = data;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
563 Subid *oidp = objid + 1;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
564 uint32_t subidentifier;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
565 int32_t length;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
566 uint32_t asn_length = 0;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
567
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
568
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
569 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
570
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
571 *type = *bufp++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
572 bufp = asn_parse_length(bufp, &asn_length, error_label);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
573 if (bufp == NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
574 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
575 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
576 if (asn_length + (uint32_t)(bufp - data) > *datalength){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
577 (void)sprintf(error_label, ERR_MSG_OVERFLOW);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
578 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
579 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
580 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
581 *datalength -= asn_length + (uint32_t)(bufp - data);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
582
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
583 length = asn_length;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
584 (*objidlength)--; /* account for expansion of first byte */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
585 while (length > 0 && (*objidlength)-- > 0){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
586 subidentifier = 0;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
587 do { /* shift and add in low order 7 bits */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
588 subidentifier = (subidentifier << 7) + (*(u_char *)bufp & ~ASN_BIT8);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
589 length--;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
590 } while (*(u_char *)bufp++ & ASN_BIT8); /* last byte has high bit clear */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
591 if (subidentifier > (uint32_t)MAX_SUBID){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
592 (void)sprintf(error_label, ERR_MSG_SUBIDENTIFIER_TOO_LONG);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
593 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
594 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
595 *oidp++ = (Subid)subidentifier;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
596 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
597
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
598 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
599 * The first two subidentifiers are encoded into the first component
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
600 * with the value (X * 40) + Y, where:
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
601 * X is the value of the first subidentifier.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
602 * Y is the value of the second subidentifier.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
603 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
604 subidentifier = (uint32_t)objid[1];
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
605 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
606 objid[1] = (u_char)(subidentifier % 0x28);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
607 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
608 objid[0] = (u_char)((subidentifier - objid[1]) / 0x28);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
609
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
610 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
611 *objidlength = (int32_t)(oidp - objid);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
612 return bufp;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
613 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
614
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
615 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
616 * asn_build_objid - Builds an ASN object identifier object containing the input string.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
617 * On entry, datalength is input as the number of valid bytes following
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
618 * "data". On exit, it is returned as the number of valid bytes
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
619 * following the beginning of the next object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
620 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
621 * Returns a pointer to the first byte past the end
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
622 * of this object (i.e. the start of the next object).
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
623 * Returns NULL on any error.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
624 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
625 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
626 asn_build_objid(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
627 u_char *data, /* IN - pointer to start of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
628 uint32_t *datalength, /* IN/OUT - number of valid bytes left in buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
629 u_char type, /* IN - ASN type of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
630 Subid *objid, /* IN - pointer to start of input buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
631 int32_t objidlength, /* IN - number of sub-id's in objid */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
632 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
633 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
634 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
635 * ASN.1 objid ::= 0x06 asnlength subidentifier {subidentifier}*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
636 * subidentifier ::= {leadingbyte}* lastbyte
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
637 * leadingbyte ::= 1 7bitvalue
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
638 * lastbyte ::= 0 7bitvalue
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
639 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
640
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
641 uchar_t buf[MAX_OID_LEN * 5];
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
642 uchar_t *bp = buf;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
643 Subid objbuf[MAX_OID_LEN];
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
644 Subid *op = objbuf;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
645 uint32_t asnlength;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
646 uint32_t subid, mask, testmask;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
647 int bits, testbits;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
648
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
649 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
650
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
651 if (objidlength > MAX_OID_LEN)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
652 return (NULL);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
653
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
654 memcpy(objbuf, objid, objidlength * (int32_t)sizeof (Subid));
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
655 /* transform size in bytes to size in subid's */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
656 /* encode the first two components into the first subidentifier */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
657 op[1] = op[1] + (op[0] * 40);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
658 op++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
659 objidlength--;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
660
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
661 while (objidlength-- > 0){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
662 subid = *op++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
663 mask = 0x7F; /* handle subid == 0 case */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
664 bits = 0;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
665 /* testmask *MUST* !!!! be of an unsigned type */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
666 for (testmask = 0x7F, testbits = 0; testmask != 0;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
667 testmask <<= 7, testbits += 7) {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
668 if (subid & testmask) { /* if any bits set */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
669 mask = testmask;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
670 bits = testbits;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
671 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
672 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
673 /* mask can't be zero here */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
674 for (; mask != 0x7F; mask >>= 7, bits -= 7){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
675 if (mask == 0x1E00000)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
676 /* fix a mask that got truncated above */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
677 mask = 0xFE00000;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
678 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
679 *bp++ = (uchar_t)(((subid & mask) >> bits) | ASN_BIT8);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
680 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
681 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
682 *bp++ = (uchar_t)(subid & mask);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
683 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
684 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
685 asnlength = (uint32_t)(bp - buf);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
686 data = asn_build_header(data, datalength, type, asnlength, error_label);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
687 if (data == NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
688 return (NULL);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
689 if (*datalength < asnlength)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
690 return (NULL);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
691 memcpy(data, buf, asnlength);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
692 *datalength -= asnlength;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
693 return (data + (uintptr_t)asnlength);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
694 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
695
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
696 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
697 * asn_parse_null - Interprets an ASN null type.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
698 * On entry, datalength is input as the number of valid bytes following
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
699 * "data". On exit, it is returned as the number of valid bytes
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
700 * following the beginning of the next object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
701 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
702 * Returns a pointer to the first byte past the end
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
703 * of this object (i.e. the start of the next object).
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
704 * Returns NULL on any error.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
705 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
706 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
707 asn_parse_null(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
708 u_char *data, /* IN - pointer to start of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
709 uint32_t *datalength, /* IN/OUT - number of valid bytes left in buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
710 u_char *type, /* OUT - ASN type of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
711 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
712 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
713 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
714 * ASN.1 null ::= 0x05 0x00
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
715 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
716 u_char *bufp = data;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
717 uint32_t asn_length = 0;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
718
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
719
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
720 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
721
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
722 *type = *bufp++;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
723 bufp = asn_parse_length(bufp, &asn_length, error_label);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
724 if (bufp == NULL)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
725 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
726 if (asn_length != 0){
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
727 (void)sprintf(error_label, ERR_MSG_MALFORMED_NULL);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
728 return NULL;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
729 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
730 /* LINTED */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
731 *datalength -= (uint32_t)(bufp - data);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
732 return bufp + (uintptr_t)asn_length;
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
733 }
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
734
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
735 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
736 * asn_build_null - Builds an ASN null object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
737 * On entry, datalength is input as the number of valid bytes following
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
738 * "data". On exit, it is returned as the number of valid bytes
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
739 * following the beginning of the next object.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
740 *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
741 * Returns a pointer to the first byte past the end
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
742 * of this object (i.e. the start of the next object).
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
743 * Returns NULL on any error.
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
744 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
745 u_char *
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
746 asn_build_null(
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
747 u_char *data, /* IN - pointer to start of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
748 uint32_t *datalength, /* IN/OUT - number of valid bytes left in buffer */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
749 u_char type, /* IN - ASN type of object */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
750 char *error_label)
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
751 {
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
752 /*
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
753 * ASN.1 null ::= 0x05 0x00
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
754 */
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
755 error_label[0] = '\0';
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
756
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
757 return asn_build_header(data, datalength, type, 0, error_label);
c9caec207d52 Initial porting based on b86
Koji Uno <koji.uno@sun.com>
parents:
diff changeset
758 }