summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/asn1/a_set.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/asn1/a_set.c')
-rw-r--r--src/lib/libcrypto/asn1/a_set.c117
1 files changed, 94 insertions, 23 deletions
diff --git a/src/lib/libcrypto/asn1/a_set.c b/src/lib/libcrypto/asn1/a_set.c
index 17c49946cf..0f839822ff 100644
--- a/src/lib/libcrypto/asn1/a_set.c
+++ b/src/lib/libcrypto/asn1/a_set.c
@@ -58,21 +58,42 @@
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#ifndef NO_ASN1_OLD
64
65typedef struct
66 {
67 unsigned char *pbData;
68 int cbData;
69 } MYBLOB;
70
71/* SetBlobCmp
72 * This function compares two elements of SET_OF block
64 */ 73 */
74static int SetBlobCmp(const void *elem1, const void *elem2 )
75 {
76 const MYBLOB *b1 = (const MYBLOB *)elem1;
77 const MYBLOB *b2 = (const MYBLOB *)elem2;
78 int r;
79
80 r = memcmp(b1->pbData, b2->pbData,
81 b1->cbData < b2->cbData ? b1->cbData : b2->cbData);
82 if(r != 0)
83 return r;
84 return b1->cbData-b2->cbData;
85 }
65 86
66int i2d_ASN1_SET(a,pp,func,ex_tag,ex_class) 87/* int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) */
67STACK *a; 88int i2d_ASN1_SET(STACK *a, unsigned char **pp, int (*func)(), int ex_tag,
68unsigned char **pp; 89 int ex_class, int is_set)
69int (*func)();
70int ex_tag;
71int ex_class;
72 { 90 {
73 int ret=0,r; 91 int ret=0,r;
74 int i; 92 int i;
75 unsigned char *p; 93 unsigned char *p;
94 unsigned char *pStart, *pTempMem;
95 MYBLOB *rgSetBlob;
96 int totSize;
76 97
77 if (a == NULL) return(0); 98 if (a == NULL) return(0);
78 for (i=sk_num(a)-1; i>=0; i--) 99 for (i=sk_num(a)-1; i>=0; i--)
@@ -82,26 +103,64 @@ int ex_class;
82 103
83 p= *pp; 104 p= *pp;
84 ASN1_put_object(&p,1,ret,ex_tag,ex_class); 105 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 106
88 *pp=p; 107/* Modified by gp@nsj.co.jp */
89 return(r); 108 /* And then again by Ben */
90 } 109 /* And again by Steve */
110
111 if(!is_set || (sk_num(a) < 2))
112 {
113 for (i=0; i<sk_num(a); i++)
114 func(sk_value(a,i),&p);
115
116 *pp=p;
117 return(r);
118 }
91 119
92STACK *d2i_ASN1_SET(a,pp,length,func,ex_tag,ex_class) 120 pStart = p; /* Catch the beg of Setblobs*/
93STACK **a; 121 if (!(rgSetBlob = (MYBLOB *)OPENSSL_malloc( sk_num(a) * sizeof(MYBLOB)))) return 0; /* In this array
94unsigned char **pp; 122we will store the SET blobs */
95long length; 123
96char *(*func)(); 124 for (i=0; i<sk_num(a); i++)
97int ex_tag; 125 {
98int ex_class; 126 rgSetBlob[i].pbData = p; /* catch each set encode blob */
127 func(sk_value(a,i),&p);
128 rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this
129SetBlob
130*/
131 }
132 *pp=p;
133 totSize = p - pStart; /* This is the total size of all set blobs */
134
135 /* Now we have to sort the blobs. I am using a simple algo.
136 *Sort ptrs *Copy to temp-mem *Copy from temp-mem to user-mem*/
137 qsort( rgSetBlob, sk_num(a), sizeof(MYBLOB), SetBlobCmp);
138 if (!(pTempMem = OPENSSL_malloc(totSize))) return 0;
139
140/* Copy to temp mem */
141 p = pTempMem;
142 for(i=0; i<sk_num(a); ++i)
143 {
144 memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
145 p += rgSetBlob[i].cbData;
146 }
147
148/* Copy back to user mem*/
149 memcpy(pStart, pTempMem, totSize);
150 OPENSSL_free(pTempMem);
151 OPENSSL_free(rgSetBlob);
152
153 return(r);
154 }
155
156STACK *d2i_ASN1_SET(STACK **a, unsigned char **pp, long length,
157 char *(*func)(), void (*free_func)(void *), int ex_tag, int ex_class)
99 { 158 {
100 ASN1_CTX c; 159 ASN1_CTX c;
101 STACK *ret=NULL; 160 STACK *ret=NULL;
102 161
103 if ((a == NULL) || ((*a) == NULL)) 162 if ((a == NULL) || ((*a) == NULL))
104 { if ((ret=sk_new(NULL)) == NULL) goto err; } 163 { if ((ret=sk_new_null()) == NULL) goto err; }
105 else 164 else
106 ret=(*a); 165 ret=(*a);
107 166
@@ -136,14 +195,26 @@ int ex_class;
136 char *s; 195 char *s;
137 196
138 if (M_ASN1_D2I_end_sequence()) break; 197 if (M_ASN1_D2I_end_sequence()) break;
139 if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) goto err; 198 if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL)
199 {
200 ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT);
201 asn1_add_error(*pp,(int)(c.q- *pp));
202 goto err;
203 }
140 if (!sk_push(ret,s)) goto err; 204 if (!sk_push(ret,s)) goto err;
141 } 205 }
142 if (a != NULL) (*a)=ret; 206 if (a != NULL) (*a)=ret;
143 *pp=c.p; 207 *pp=c.p;
144 return(ret); 208 return(ret);
145err: 209err:
146 if ((ret != NULL) && ((a == NULL) || (*a != ret))) sk_free(ret); 210 if ((ret != NULL) && ((a == NULL) || (*a != ret)))
211 {
212 if (free_func != NULL)
213 sk_pop_free(ret,free_func);
214 else
215 sk_free(ret);
216 }
147 return(NULL); 217 return(NULL);
148 } 218 }
149 219
220#endif