diff options
Diffstat (limited to 'src/lib/libcrypto/asn1/a_set.c')
| -rw-r--r-- | src/lib/libcrypto/asn1/a_set.c | 117 |
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 | |||
| 65 | typedef 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 | */ |
| 74 | static 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 | ||
| 66 | int 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) */ |
| 67 | STACK *a; | 88 | int i2d_ASN1_SET(STACK *a, unsigned char **pp, int (*func)(), int ex_tag, |
| 68 | unsigned char **pp; | 89 | int ex_class, int is_set) |
| 69 | int (*func)(); | ||
| 70 | int ex_tag; | ||
| 71 | int 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 | ||
| 92 | STACK *d2i_ASN1_SET(a,pp,length,func,ex_tag,ex_class) | 120 | pStart = p; /* Catch the beg of Setblobs*/ |
| 93 | STACK **a; | 121 | if (!(rgSetBlob = (MYBLOB *)OPENSSL_malloc( sk_num(a) * sizeof(MYBLOB)))) return 0; /* In this array |
| 94 | unsigned char **pp; | 122 | we will store the SET blobs */ |
| 95 | long length; | 123 | |
| 96 | char *(*func)(); | 124 | for (i=0; i<sk_num(a); i++) |
| 97 | int ex_tag; | 125 | { |
| 98 | int 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 | ||
| 129 | SetBlob | ||
| 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 | |||
| 156 | STACK *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); |
| 145 | err: | 209 | err: |
| 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 | ||
