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.c78
1 files changed, 48 insertions, 30 deletions
diff --git a/src/lib/libcrypto/asn1/a_bitstr.c b/src/lib/libcrypto/asn1/a_bitstr.c
index 2c10120651..38ea802be8 100644
--- a/src/lib/libcrypto/asn1/a_bitstr.c
+++ b/src/lib/libcrypto/asn1/a_bitstr.c
@@ -58,45 +58,60 @@
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 i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
64 * ASN1err(ASN1_F_D2I_ASN1_BIT_STRING,ASN1_R_EXPECTING_A_BIT_STRING);
65 */
66
67int i2d_ASN1_BIT_STRING(a,pp)
68ASN1_BIT_STRING *a;
69unsigned char **pp;
70 { 64 {
71 int ret,j,r,bits; 65 int ret,j,r,bits,len;
72 unsigned char *p,*d; 66 unsigned char *p,*d;
73 67
74 if (a == NULL) return(0); 68 if (a == NULL) return(0);
75 69
76 /* our bit strings are always a multiple of 8 :-) */ 70 len=a->length;
77 bits=0; 71
78 ret=1+a->length; 72 if (len > 0)
73 {
74 if (a->flags & ASN1_STRING_FLAG_BITS_LEFT)
75 {
76 bits=(int)a->flags&0x07;
77 }
78 else
79 {
80 for ( ; len > 0; len--)
81 {
82 if (a->data[len-1]) break;
83 }
84 j=a->data[len-1];
85 if (j & 0x01) bits=0;
86 else if (j & 0x02) bits=1;
87 else if (j & 0x04) bits=2;
88 else if (j & 0x08) bits=3;
89 else if (j & 0x10) bits=4;
90 else if (j & 0x20) bits=5;
91 else if (j & 0x40) bits=6;
92 else if (j & 0x80) bits=7;
93 else bits=0; /* should not happen */
94 }
95 }
96 else
97 bits=0;
98 ret=1+len;
79 r=ASN1_object_size(0,ret,V_ASN1_BIT_STRING); 99 r=ASN1_object_size(0,ret,V_ASN1_BIT_STRING);
80 if (pp == NULL) return(r); 100 if (pp == NULL) return(r);
81 p= *pp; 101 p= *pp;
82 102
83 ASN1_put_object(&p,0,ret,V_ASN1_BIT_STRING,V_ASN1_UNIVERSAL); 103 ASN1_put_object(&p,0,ret,V_ASN1_BIT_STRING,V_ASN1_UNIVERSAL);
84 if (bits == 0) 104 *(p++)=(unsigned char)bits;
85 j=0;
86 else j=8-bits;
87 *(p++)=(unsigned char)j;
88 d=a->data; 105 d=a->data;
89 memcpy(p,d,a->length); 106 memcpy(p,d,len);
90 p+=a->length; 107 p+=len;
91 if (a->length > 0) p[-1]&=(0xff<<j); 108 if (len > 0) p[-1]&=(0xff<<bits);
92 *pp=p; 109 *pp=p;
93 return(r); 110 return(r);
94 } 111 }
95 112
96ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(a, pp, length) 113ASN1_BIT_STRING *d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, unsigned char **pp,
97ASN1_BIT_STRING **a; 114 long length)
98unsigned char **pp;
99long length;
100 { 115 {
101 ASN1_BIT_STRING *ret=NULL; 116 ASN1_BIT_STRING *ret=NULL;
102 unsigned char *p,*s; 117 unsigned char *p,*s;
@@ -127,6 +142,12 @@ long length;
127 if (len < 1) { i=ASN1_R_STRING_TOO_SHORT; goto err; } 142 if (len < 1) { i=ASN1_R_STRING_TOO_SHORT; goto err; }
128 143
129 i= *(p++); 144 i= *(p++);
145 /* We do this to preserve the settings. If we modify
146 * the settings, via the _set_bit function, we will recalculate
147 * on output */
148 ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
149 ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
150
130 if (len-- > 1) /* using one because of the bits left byte */ 151 if (len-- > 1) /* using one because of the bits left byte */
131 { 152 {
132 s=(unsigned char *)Malloc((int)len); 153 s=(unsigned char *)Malloc((int)len);
@@ -158,10 +179,7 @@ err:
158 179
159/* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de> 180/* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
160 */ 181 */
161int ASN1_BIT_STRING_set_bit(a,n,value) 182int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
162ASN1_BIT_STRING *a;
163int n;
164int value;
165 { 183 {
166 int w,v,iv; 184 int w,v,iv;
167 unsigned char *c; 185 unsigned char *c;
@@ -170,6 +188,8 @@ int value;
170 v=1<<(7-(n&0x07)); 188 v=1<<(7-(n&0x07));
171 iv= ~v; 189 iv= ~v;
172 190
191 a->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear, set on write */
192
173 if (a == NULL) return(0); 193 if (a == NULL) return(0);
174 if ((a->length < (w+1)) || (a->data == NULL)) 194 if ((a->length < (w+1)) || (a->data == NULL))
175 { 195 {
@@ -189,9 +209,7 @@ int value;
189 return(1); 209 return(1);
190 } 210 }
191 211
192int ASN1_BIT_STRING_get_bit(a,n) 212int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
193ASN1_BIT_STRING *a;
194int n;
195 { 213 {
196 int w,v; 214 int w,v;
197 215