diff options
author | beck <> | 1999-09-29 04:37:45 +0000 |
---|---|---|
committer | beck <> | 1999-09-29 04:37:45 +0000 |
commit | de8f24ea083384bb66b32ec105dc4743c5663cdf (patch) | |
tree | 1412176ae62a3cab2cf2b0b92150fcbceaac6092 /src/lib/libcrypto/asn1/a_set.c | |
parent | cb929d29896bcb87c2a97417fbd03e50078fc178 (diff) | |
download | openbsd-de8f24ea083384bb66b32ec105dc4743c5663cdf.tar.gz openbsd-de8f24ea083384bb66b32ec105dc4743c5663cdf.tar.bz2 openbsd-de8f24ea083384bb66b32ec105dc4743c5663cdf.zip |
OpenSSL 0.9.4 merge
Diffstat (limited to 'src/lib/libcrypto/asn1/a_set.c')
-rw-r--r-- | src/lib/libcrypto/asn1/a_set.c | 112 |
1 files changed, 90 insertions, 22 deletions
diff --git a/src/lib/libcrypto/asn1/a_set.c b/src/lib/libcrypto/asn1/a_set.c index 17c49946cf..c2481e7597 100644 --- a/src/lib/libcrypto/asn1/a_set.c +++ b/src/lib/libcrypto/asn1/a_set.c | |||
@@ -58,21 +58,40 @@ | |||
58 | 58 | ||
59 | #include <stdio.h> | 59 | #include <stdio.h> |
60 | #include "cryptlib.h" | 60 | #include "cryptlib.h" |
61 | #include "asn1_mac.h" | 61 | #include <openssl/asn1_mac.h> |
62 | 62 | ||
63 | /* ASN1err(ASN1_F_ASN1_TYPE_NEW,ERR_R_MALLOC_FAILURE); | 63 | typedef struct |
64 | { | ||
65 | unsigned char *pbData; | ||
66 | int cbData; | ||
67 | } MYBLOB; | ||
68 | |||
69 | /* SetBlobCmp | ||
70 | * This function compares two elements of SET_OF block | ||
64 | */ | 71 | */ |
72 | static int SetBlobCmp(const void *elem1, const void *elem2 ) | ||
73 | { | ||
74 | const MYBLOB *b1 = (const MYBLOB *)elem1; | ||
75 | const MYBLOB *b2 = (const MYBLOB *)elem2; | ||
76 | int r; | ||
77 | |||
78 | r = memcmp(b1->pbData, b2->pbData, | ||
79 | b1->cbData < b2->cbData ? b1->cbData : b2->cbData); | ||
80 | if(r != 0) | ||
81 | return r; | ||
82 | return b1->cbData-b2->cbData; | ||
83 | } | ||
65 | 84 | ||
66 | int i2d_ASN1_SET(a,pp,func,ex_tag,ex_class) | 85 | /* int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) */ |
67 | STACK *a; | 86 | int i2d_ASN1_SET(STACK *a, unsigned char **pp, int (*func)(), int ex_tag, |
68 | unsigned char **pp; | 87 | int ex_class, int is_set) |
69 | int (*func)(); | ||
70 | int ex_tag; | ||
71 | int ex_class; | ||
72 | { | 88 | { |
73 | int ret=0,r; | 89 | int ret=0,r; |
74 | int i; | 90 | int i; |
75 | unsigned char *p; | 91 | unsigned char *p; |
92 | unsigned char *pStart, *pTempMem; | ||
93 | MYBLOB *rgSetBlob; | ||
94 | int totSize; | ||
76 | 95 | ||
77 | if (a == NULL) return(0); | 96 | if (a == NULL) return(0); |
78 | for (i=sk_num(a)-1; i>=0; i--) | 97 | for (i=sk_num(a)-1; i>=0; i--) |
@@ -82,20 +101,58 @@ int ex_class; | |||
82 | 101 | ||
83 | p= *pp; | 102 | p= *pp; |
84 | ASN1_put_object(&p,1,ret,ex_tag,ex_class); | 103 | ASN1_put_object(&p,1,ret,ex_tag,ex_class); |
85 | for (i=0; i<sk_num(a); i++) | ||
86 | func(sk_value(a,i),&p); | ||
87 | 104 | ||
88 | *pp=p; | 105 | /* Modified by gp@nsj.co.jp */ |
89 | return(r); | 106 | /* And then again by Ben */ |
90 | } | 107 | /* And again by Steve */ |
108 | |||
109 | if(!is_set || (sk_num(a) < 2)) | ||
110 | { | ||
111 | for (i=0; i<sk_num(a); i++) | ||
112 | func(sk_value(a,i),&p); | ||
113 | |||
114 | *pp=p; | ||
115 | return(r); | ||
116 | } | ||
117 | |||
118 | pStart = p; /* Catch the beg of Setblobs*/ | ||
119 | rgSetBlob = (MYBLOB *)Malloc( sk_num(a) * sizeof(MYBLOB)); /* In this array | ||
120 | we will store the SET blobs */ | ||
121 | |||
122 | for (i=0; i<sk_num(a); i++) | ||
123 | { | ||
124 | rgSetBlob[i].pbData = p; /* catch each set encode blob */ | ||
125 | func(sk_value(a,i),&p); | ||
126 | rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this | ||
127 | SetBlob | ||
128 | */ | ||
129 | } | ||
130 | *pp=p; | ||
131 | totSize = p - pStart; /* This is the total size of all set blobs */ | ||
132 | |||
133 | /* Now we have to sort the blobs. I am using a simple algo. | ||
134 | *Sort ptrs *Copy to temp-mem *Copy from temp-mem to user-mem*/ | ||
135 | qsort( rgSetBlob, sk_num(a), sizeof(MYBLOB), SetBlobCmp); | ||
136 | pTempMem = Malloc(totSize); | ||
137 | |||
138 | /* Copy to temp mem */ | ||
139 | p = pTempMem; | ||
140 | for(i=0; i<sk_num(a); ++i) | ||
141 | { | ||
142 | memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData); | ||
143 | p += rgSetBlob[i].cbData; | ||
144 | } | ||
91 | 145 | ||
92 | STACK *d2i_ASN1_SET(a,pp,length,func,ex_tag,ex_class) | 146 | /* Copy back to user mem*/ |
93 | STACK **a; | 147 | memcpy(pStart, pTempMem, totSize); |
94 | unsigned char **pp; | 148 | Free(pTempMem); |
95 | long length; | 149 | Free(rgSetBlob); |
96 | char *(*func)(); | 150 | |
97 | int ex_tag; | 151 | return(r); |
98 | int ex_class; | 152 | } |
153 | |||
154 | STACK *d2i_ASN1_SET(STACK **a, unsigned char **pp, long length, | ||
155 | char *(*func)(), void (*free_func)(), int ex_tag, int ex_class) | ||
99 | { | 156 | { |
100 | ASN1_CTX c; | 157 | ASN1_CTX c; |
101 | STACK *ret=NULL; | 158 | STACK *ret=NULL; |
@@ -136,14 +193,25 @@ int ex_class; | |||
136 | char *s; | 193 | char *s; |
137 | 194 | ||
138 | if (M_ASN1_D2I_end_sequence()) break; | 195 | if (M_ASN1_D2I_end_sequence()) break; |
139 | if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) goto err; | 196 | if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) |
197 | { | ||
198 | ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT); | ||
199 | asn1_add_error(*pp,(int)(c.q- *pp)); | ||
200 | goto err; | ||
201 | } | ||
140 | if (!sk_push(ret,s)) goto err; | 202 | if (!sk_push(ret,s)) goto err; |
141 | } | 203 | } |
142 | if (a != NULL) (*a)=ret; | 204 | if (a != NULL) (*a)=ret; |
143 | *pp=c.p; | 205 | *pp=c.p; |
144 | return(ret); | 206 | return(ret); |
145 | err: | 207 | err: |
146 | if ((ret != NULL) && ((a == NULL) || (*a != ret))) sk_free(ret); | 208 | if ((ret != NULL) && ((a == NULL) || (*a != ret))) |
209 | { | ||
210 | if (free_func != NULL) | ||
211 | sk_pop_free(ret,free_func); | ||
212 | else | ||
213 | sk_free(ret); | ||
214 | } | ||
147 | return(NULL); | 215 | return(NULL); |
148 | } | 216 | } |
149 | 217 | ||