summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/asn1/a_bitstr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/asn1/a_bitstr.c')
-rw-r--r--src/lib/libcrypto/asn1/a_bitstr.c120
1 files changed, 63 insertions, 57 deletions
diff --git a/src/lib/libcrypto/asn1/a_bitstr.c b/src/lib/libcrypto/asn1/a_bitstr.c
index 2c10120651..ed0bdfbde1 100644
--- a/src/lib/libcrypto/asn1/a_bitstr.c
+++ b/src/lib/libcrypto/asn1/a_bitstr.c
@@ -58,78 +58,86 @@
58 58
59#include <stdio.h> 59#include <stdio.h>
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include "asn1.h" 61#include <openssl/asn1.h>
62 62
63/* ASN1err(ASN1_F_ASN1_STRING_NEW,ASN1_R_STRING_TOO_SHORT); 63int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
64 * ASN1err(ASN1_F_D2I_ASN1_BIT_STRING,ASN1_R_EXPECTING_A_BIT_STRING); 64{ return M_ASN1_BIT_STRING_set(x, d, len); }
65 */
66 65
67int i2d_ASN1_BIT_STRING(a,pp) 66int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
68ASN1_BIT_STRING *a;
69unsigned char **pp;
70 { 67 {
71 int ret,j,r,bits; 68 int ret,j,bits,len;
72 unsigned char *p,*d; 69 unsigned char *p,*d;
73 70
74 if (a == NULL) return(0); 71 if (a == NULL) return(0);
75 72
76 /* our bit strings are always a multiple of 8 :-) */ 73 len=a->length;
77 bits=0; 74
78 ret=1+a->length; 75 if (len > 0)
79 r=ASN1_object_size(0,ret,V_ASN1_BIT_STRING); 76 {
80 if (pp == NULL) return(r); 77 if (a->flags & ASN1_STRING_FLAG_BITS_LEFT)
78 {
79 bits=(int)a->flags&0x07;
80 }
81 else
82 {
83 for ( ; len > 0; len--)
84 {
85 if (a->data[len-1]) break;
86 }
87 j=a->data[len-1];
88 if (j & 0x01) bits=0;
89 else if (j & 0x02) bits=1;
90 else if (j & 0x04) bits=2;
91 else if (j & 0x08) bits=3;
92 else if (j & 0x10) bits=4;
93 else if (j & 0x20) bits=5;
94 else if (j & 0x40) bits=6;
95 else if (j & 0x80) bits=7;
96 else bits=0; /* should not happen */
97 }
98 }
99 else
100 bits=0;
101
102 ret=1+len;
103 if (pp == NULL) return(ret);
104
81 p= *pp; 105 p= *pp;
82 106
83 ASN1_put_object(&p,0,ret,V_ASN1_BIT_STRING,V_ASN1_UNIVERSAL); 107 *(p++)=(unsigned char)bits;
84 if (bits == 0)
85 j=0;
86 else j=8-bits;
87 *(p++)=(unsigned char)j;
88 d=a->data; 108 d=a->data;
89 memcpy(p,d,a->length); 109 memcpy(p,d,len);
90 p+=a->length; 110 p+=len;
91 if (a->length > 0) p[-1]&=(0xff<<j); 111 if (len > 0) p[-1]&=(0xff<<bits);
92 *pp=p; 112 *pp=p;
93 return(r); 113 return(ret);
94 } 114 }
95 115
96ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(a, pp, length) 116ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp,
97ASN1_BIT_STRING **a; 117 long len)
98unsigned char **pp;
99long length;
100 { 118 {
101 ASN1_BIT_STRING *ret=NULL; 119 ASN1_BIT_STRING *ret=NULL;
102 unsigned char *p,*s; 120 unsigned char *p,*s;
103 long len;
104 int inf,tag,xclass;
105 int i; 121 int i;
106 122
107 if ((a == NULL) || ((*a) == NULL)) 123 if ((a == NULL) || ((*a) == NULL))
108 { 124 {
109 if ((ret=ASN1_BIT_STRING_new()) == NULL) return(NULL); 125 if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL);
110 } 126 }
111 else 127 else
112 ret=(*a); 128 ret=(*a);
113 129
114 p= *pp; 130 p= *pp;
115 inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
116 if (inf & 0x80)
117 {
118 i=ASN1_R_BAD_OBJECT_HEADER;
119 goto err;
120 }
121
122 if (tag != V_ASN1_BIT_STRING)
123 {
124 i=ASN1_R_EXPECTING_A_BIT_STRING;
125 goto err;
126 }
127 if (len < 1) { i=ASN1_R_STRING_TOO_SHORT; goto err; }
128
129 i= *(p++); 131 i= *(p++);
132 /* We do this to preserve the settings. If we modify
133 * the settings, via the _set_bit function, we will recalculate
134 * on output */
135 ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
136 ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
137
130 if (len-- > 1) /* using one because of the bits left byte */ 138 if (len-- > 1) /* using one because of the bits left byte */
131 { 139 {
132 s=(unsigned char *)Malloc((int)len); 140 s=(unsigned char *)OPENSSL_malloc((int)len);
133 if (s == NULL) 141 if (s == NULL)
134 { 142 {
135 i=ERR_R_MALLOC_FAILURE; 143 i=ERR_R_MALLOC_FAILURE;
@@ -143,7 +151,7 @@ long length;
143 s=NULL; 151 s=NULL;
144 152
145 ret->length=(int)len; 153 ret->length=(int)len;
146 if (ret->data != NULL) Free((char *)ret->data); 154 if (ret->data != NULL) OPENSSL_free(ret->data);
147 ret->data=s; 155 ret->data=s;
148 ret->type=V_ASN1_BIT_STRING; 156 ret->type=V_ASN1_BIT_STRING;
149 if (a != NULL) (*a)=ret; 157 if (a != NULL) (*a)=ret;
@@ -152,16 +160,13 @@ long length;
152err: 160err:
153 ASN1err(ASN1_F_D2I_ASN1_BIT_STRING,i); 161 ASN1err(ASN1_F_D2I_ASN1_BIT_STRING,i);
154 if ((ret != NULL) && ((a == NULL) || (*a != ret))) 162 if ((ret != NULL) && ((a == NULL) || (*a != ret)))
155 ASN1_BIT_STRING_free(ret); 163 M_ASN1_BIT_STRING_free(ret);
156 return(NULL); 164 return(NULL);
157 } 165 }
158 166
159/* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de> 167/* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
160 */ 168 */
161int ASN1_BIT_STRING_set_bit(a,n,value) 169int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
162ASN1_BIT_STRING *a;
163int n;
164int value;
165 { 170 {
166 int w,v,iv; 171 int w,v,iv;
167 unsigned char *c; 172 unsigned char *c;
@@ -169,29 +174,30 @@ int value;
169 w=n/8; 174 w=n/8;
170 v=1<<(7-(n&0x07)); 175 v=1<<(7-(n&0x07));
171 iv= ~v; 176 iv= ~v;
177 if (!value) v=0;
178
179 a->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear, set on write */
172 180
173 if (a == NULL) return(0); 181 if (a == NULL) return(0);
174 if ((a->length < (w+1)) || (a->data == NULL)) 182 if ((a->length < (w+1)) || (a->data == NULL))
175 { 183 {
176 if (!value) return(1); /* Don't need to set */ 184 if (!value) return(1); /* Don't need to set */
177 if (a->data == NULL) 185 if (a->data == NULL)
178 c=(unsigned char *)Malloc(w+1); 186 c=(unsigned char *)OPENSSL_malloc(w+1);
179 else 187 else
180 c=(unsigned char *)Realloc(a->data,w+1); 188 c=(unsigned char *)OPENSSL_realloc(a->data,w+1);
181 if (c == NULL) return(0); 189 if (c == NULL) return(0);
190 if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length);
182 a->data=c; 191 a->data=c;
183 a->length=w+1; 192 a->length=w+1;
184 c[w]=0; 193 }
185 }
186 a->data[w]=((a->data[w])&iv)|v; 194 a->data[w]=((a->data[w])&iv)|v;
187 while ((a->length > 0) && (a->data[a->length-1] == 0)) 195 while ((a->length > 0) && (a->data[a->length-1] == 0))
188 a->length--; 196 a->length--;
189 return(1); 197 return(1);
190 } 198 }
191 199
192int ASN1_BIT_STRING_get_bit(a,n) 200int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
193ASN1_BIT_STRING *a;
194int n;
195 { 201 {
196 int w,v; 202 int w,v;
197 203