| OLD | NEW |
| (Empty) |
| 1 #include <stdio.h> | |
| 2 #include <stdlib.h> | |
| 3 #include <string.h> | |
| 4 #include <openssl/pkcs7.h> | |
| 5 #include <openssl/asn1_mac.h> | |
| 6 #include <openssl/x509.h> | |
| 7 | |
| 8 int add_signed_time(PKCS7_SIGNER_INFO *si) | |
| 9 { | |
| 10 ASN1_UTCTIME *sign_time; | |
| 11 | |
| 12 /* The last parameter is the amount to add/subtract from the current | |
| 13 * time (in seconds) */ | |
| 14 sign_time=X509_gmtime_adj(NULL,0); | |
| 15 PKCS7_add_signed_attribute(si,NID_pkcs9_signingTime, | |
| 16 V_ASN1_UTCTIME,(char *)sign_time); | |
| 17 return(1); | |
| 18 } | |
| 19 | |
| 20 ASN1_UTCTIME *get_signed_time(PKCS7_SIGNER_INFO *si) | |
| 21 { | |
| 22 ASN1_TYPE *so; | |
| 23 | |
| 24 so=PKCS7_get_signed_attribute(si,NID_pkcs9_signingTime); | |
| 25 if (so->type == V_ASN1_UTCTIME) | |
| 26 return so->value.utctime; | |
| 27 return NULL; | |
| 28 } | |
| 29 | |
| 30 static int signed_string_nid= -1; | |
| 31 | |
| 32 void add_signed_string(PKCS7_SIGNER_INFO *si, char *str) | |
| 33 { | |
| 34 ASN1_OCTET_STRING *os; | |
| 35 | |
| 36 /* To a an object of OID 1.2.3.4.5, which is an octet string */ | |
| 37 if (signed_string_nid == -1) | |
| 38 signed_string_nid= | |
| 39 OBJ_create("1.2.3.4.5","OID_example","Our example OID"); | |
| 40 os=ASN1_OCTET_STRING_new(); | |
| 41 ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str)); | |
| 42 /* When we add, we do not free */ | |
| 43 PKCS7_add_signed_attribute(si,signed_string_nid, | |
| 44 V_ASN1_OCTET_STRING,(char *)os); | |
| 45 } | |
| 46 | |
| 47 int get_signed_string(PKCS7_SIGNER_INFO *si, char *buf, int len) | |
| 48 { | |
| 49 ASN1_TYPE *so; | |
| 50 ASN1_OCTET_STRING *os; | |
| 51 int i; | |
| 52 | |
| 53 if (signed_string_nid == -1) | |
| 54 signed_string_nid= | |
| 55 OBJ_create("1.2.3.4.5","OID_example","Our example OID"); | |
| 56 /* To retrieve */ | |
| 57 so=PKCS7_get_signed_attribute(si,signed_string_nid); | |
| 58 if (so != NULL) | |
| 59 { | |
| 60 if (so->type == V_ASN1_OCTET_STRING) | |
| 61 { | |
| 62 os=so->value.octet_string; | |
| 63 i=os->length; | |
| 64 if ((i+1) > len) | |
| 65 i=len-1; | |
| 66 memcpy(buf,os->data,i); | |
| 67 return(i); | |
| 68 } | |
| 69 } | |
| 70 return(0); | |
| 71 } | |
| 72 | |
| 73 static int signed_seq2string_nid= -1; | |
| 74 /* ########################################### */ | |
| 75 int add_signed_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2) | |
| 76 { | |
| 77 /* To add an object of OID 1.9.999, which is a sequence containing | |
| 78 * 2 octet strings */ | |
| 79 unsigned char *p; | |
| 80 ASN1_OCTET_STRING *os1,*os2; | |
| 81 ASN1_STRING *seq; | |
| 82 unsigned char *data; | |
| 83 int i,total; | |
| 84 | |
| 85 if (signed_seq2string_nid == -1) | |
| 86 signed_seq2string_nid= | |
| 87 OBJ_create("1.9.9999","OID_example","Our example OID"); | |
| 88 | |
| 89 os1=ASN1_OCTET_STRING_new(); | |
| 90 os2=ASN1_OCTET_STRING_new(); | |
| 91 ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1)); | |
| 92 ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1)); | |
| 93 i =i2d_ASN1_OCTET_STRING(os1,NULL); | |
| 94 i+=i2d_ASN1_OCTET_STRING(os2,NULL); | |
| 95 total=ASN1_object_size(1,i,V_ASN1_SEQUENCE); | |
| 96 | |
| 97 data=malloc(total); | |
| 98 p=data; | |
| 99 ASN1_put_object(&p,1,i,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL); | |
| 100 i2d_ASN1_OCTET_STRING(os1,&p); | |
| 101 i2d_ASN1_OCTET_STRING(os2,&p); | |
| 102 | |
| 103 seq=ASN1_STRING_new(); | |
| 104 ASN1_STRING_set(seq,data,total); | |
| 105 free(data); | |
| 106 ASN1_OCTET_STRING_free(os1); | |
| 107 ASN1_OCTET_STRING_free(os2); | |
| 108 | |
| 109 PKCS7_add_signed_attribute(si,signed_seq2string_nid, | |
| 110 V_ASN1_SEQUENCE,(char *)seq); | |
| 111 return(1); | |
| 112 } | |
| 113 | |
| 114 /* For this case, I will malloc the return strings */ | |
| 115 int get_signed_seq2string(PKCS7_SIGNER_INFO *si, char **str1, char **str2) | |
| 116 { | |
| 117 ASN1_TYPE *so; | |
| 118 | |
| 119 if (signed_seq2string_nid == -1) | |
| 120 signed_seq2string_nid= | |
| 121 OBJ_create("1.9.9999","OID_example","Our example OID"); | |
| 122 /* To retrieve */ | |
| 123 so=PKCS7_get_signed_attribute(si,signed_seq2string_nid); | |
| 124 if (so && (so->type == V_ASN1_SEQUENCE)) | |
| 125 { | |
| 126 ASN1_const_CTX c; | |
| 127 ASN1_STRING *s; | |
| 128 long length; | |
| 129 ASN1_OCTET_STRING *os1,*os2; | |
| 130 | |
| 131 s=so->value.sequence; | |
| 132 c.p=ASN1_STRING_data(s); | |
| 133 c.max=c.p+ASN1_STRING_length(s); | |
| 134 if (!asn1_GetSequence(&c,&length)) goto err; | |
| 135 /* Length is the length of the seqence */ | |
| 136 | |
| 137 c.q=c.p; | |
| 138 if ((os1=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) | |
| 139 goto err; | |
| 140 c.slen-=(c.p-c.q); | |
| 141 | |
| 142 c.q=c.p; | |
| 143 if ((os2=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) | |
| 144 goto err; | |
| 145 c.slen-=(c.p-c.q); | |
| 146 | |
| 147 if (!asn1_const_Finish(&c)) goto err; | |
| 148 *str1=malloc(os1->length+1); | |
| 149 *str2=malloc(os2->length+1); | |
| 150 memcpy(*str1,os1->data,os1->length); | |
| 151 memcpy(*str2,os2->data,os2->length); | |
| 152 (*str1)[os1->length]='\0'; | |
| 153 (*str2)[os2->length]='\0'; | |
| 154 ASN1_OCTET_STRING_free(os1); | |
| 155 ASN1_OCTET_STRING_free(os2); | |
| 156 return(1); | |
| 157 } | |
| 158 err: | |
| 159 return(0); | |
| 160 } | |
| 161 | |
| 162 | |
| 163 /* ####################################### | |
| 164 * THE OTHER WAY TO DO THINGS | |
| 165 * ####################################### | |
| 166 */ | |
| 167 X509_ATTRIBUTE *create_time(void) | |
| 168 { | |
| 169 ASN1_UTCTIME *sign_time; | |
| 170 X509_ATTRIBUTE *ret; | |
| 171 | |
| 172 /* The last parameter is the amount to add/subtract from the current | |
| 173 * time (in seconds) */ | |
| 174 sign_time=X509_gmtime_adj(NULL,0); | |
| 175 ret=X509_ATTRIBUTE_create(NID_pkcs9_signingTime, | |
| 176 V_ASN1_UTCTIME,(char *)sign_time); | |
| 177 return(ret); | |
| 178 } | |
| 179 | |
| 180 ASN1_UTCTIME *sk_get_time(STACK_OF(X509_ATTRIBUTE) *sk) | |
| 181 { | |
| 182 ASN1_TYPE *so; | |
| 183 PKCS7_SIGNER_INFO si; | |
| 184 | |
| 185 si.auth_attr=sk; | |
| 186 so=PKCS7_get_signed_attribute(&si,NID_pkcs9_signingTime); | |
| 187 if (so->type == V_ASN1_UTCTIME) | |
| 188 return so->value.utctime; | |
| 189 return NULL; | |
| 190 } | |
| 191 | |
| 192 X509_ATTRIBUTE *create_string(char *str) | |
| 193 { | |
| 194 ASN1_OCTET_STRING *os; | |
| 195 X509_ATTRIBUTE *ret; | |
| 196 | |
| 197 /* To a an object of OID 1.2.3.4.5, which is an octet string */ | |
| 198 if (signed_string_nid == -1) | |
| 199 signed_string_nid= | |
| 200 OBJ_create("1.2.3.4.5","OID_example","Our example OID"); | |
| 201 os=ASN1_OCTET_STRING_new(); | |
| 202 ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str)); | |
| 203 /* When we add, we do not free */ | |
| 204 ret=X509_ATTRIBUTE_create(signed_string_nid, | |
| 205 V_ASN1_OCTET_STRING,(char *)os); | |
| 206 return(ret); | |
| 207 } | |
| 208 | |
| 209 int sk_get_string(STACK_OF(X509_ATTRIBUTE) *sk, char *buf, int len) | |
| 210 { | |
| 211 ASN1_TYPE *so; | |
| 212 ASN1_OCTET_STRING *os; | |
| 213 int i; | |
| 214 PKCS7_SIGNER_INFO si; | |
| 215 | |
| 216 si.auth_attr=sk; | |
| 217 | |
| 218 if (signed_string_nid == -1) | |
| 219 signed_string_nid= | |
| 220 OBJ_create("1.2.3.4.5","OID_example","Our example OID"); | |
| 221 /* To retrieve */ | |
| 222 so=PKCS7_get_signed_attribute(&si,signed_string_nid); | |
| 223 if (so != NULL) | |
| 224 { | |
| 225 if (so->type == V_ASN1_OCTET_STRING) | |
| 226 { | |
| 227 os=so->value.octet_string; | |
| 228 i=os->length; | |
| 229 if ((i+1) > len) | |
| 230 i=len-1; | |
| 231 memcpy(buf,os->data,i); | |
| 232 return(i); | |
| 233 } | |
| 234 } | |
| 235 return(0); | |
| 236 } | |
| 237 | |
| 238 X509_ATTRIBUTE *add_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2) | |
| 239 { | |
| 240 /* To add an object of OID 1.9.999, which is a sequence containing | |
| 241 * 2 octet strings */ | |
| 242 unsigned char *p; | |
| 243 ASN1_OCTET_STRING *os1,*os2; | |
| 244 ASN1_STRING *seq; | |
| 245 X509_ATTRIBUTE *ret; | |
| 246 unsigned char *data; | |
| 247 int i,total; | |
| 248 | |
| 249 if (signed_seq2string_nid == -1) | |
| 250 signed_seq2string_nid= | |
| 251 OBJ_create("1.9.9999","OID_example","Our example OID"); | |
| 252 | |
| 253 os1=ASN1_OCTET_STRING_new(); | |
| 254 os2=ASN1_OCTET_STRING_new(); | |
| 255 ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1)); | |
| 256 ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1)); | |
| 257 i =i2d_ASN1_OCTET_STRING(os1,NULL); | |
| 258 i+=i2d_ASN1_OCTET_STRING(os2,NULL); | |
| 259 total=ASN1_object_size(1,i,V_ASN1_SEQUENCE); | |
| 260 | |
| 261 data=malloc(total); | |
| 262 p=data; | |
| 263 ASN1_put_object(&p,1,i,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL); | |
| 264 i2d_ASN1_OCTET_STRING(os1,&p); | |
| 265 i2d_ASN1_OCTET_STRING(os2,&p); | |
| 266 | |
| 267 seq=ASN1_STRING_new(); | |
| 268 ASN1_STRING_set(seq,data,total); | |
| 269 free(data); | |
| 270 ASN1_OCTET_STRING_free(os1); | |
| 271 ASN1_OCTET_STRING_free(os2); | |
| 272 | |
| 273 ret=X509_ATTRIBUTE_create(signed_seq2string_nid, | |
| 274 V_ASN1_SEQUENCE,(char *)seq); | |
| 275 return(ret); | |
| 276 } | |
| 277 | |
| 278 /* For this case, I will malloc the return strings */ | |
| 279 int sk_get_seq2string(STACK_OF(X509_ATTRIBUTE) *sk, char **str1, char **str2) | |
| 280 { | |
| 281 ASN1_TYPE *so; | |
| 282 PKCS7_SIGNER_INFO si; | |
| 283 | |
| 284 if (signed_seq2string_nid == -1) | |
| 285 signed_seq2string_nid= | |
| 286 OBJ_create("1.9.9999","OID_example","Our example OID"); | |
| 287 | |
| 288 si.auth_attr=sk; | |
| 289 /* To retrieve */ | |
| 290 so=PKCS7_get_signed_attribute(&si,signed_seq2string_nid); | |
| 291 if (so->type == V_ASN1_SEQUENCE) | |
| 292 { | |
| 293 ASN1_const_CTX c; | |
| 294 ASN1_STRING *s; | |
| 295 long length; | |
| 296 ASN1_OCTET_STRING *os1,*os2; | |
| 297 | |
| 298 s=so->value.sequence; | |
| 299 c.p=ASN1_STRING_data(s); | |
| 300 c.max=c.p+ASN1_STRING_length(s); | |
| 301 if (!asn1_GetSequence(&c,&length)) goto err; | |
| 302 /* Length is the length of the seqence */ | |
| 303 | |
| 304 c.q=c.p; | |
| 305 if ((os1=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) | |
| 306 goto err; | |
| 307 c.slen-=(c.p-c.q); | |
| 308 | |
| 309 c.q=c.p; | |
| 310 if ((os2=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) | |
| 311 goto err; | |
| 312 c.slen-=(c.p-c.q); | |
| 313 | |
| 314 if (!asn1_const_Finish(&c)) goto err; | |
| 315 *str1=malloc(os1->length+1); | |
| 316 *str2=malloc(os2->length+1); | |
| 317 memcpy(*str1,os1->data,os1->length); | |
| 318 memcpy(*str2,os2->data,os2->length); | |
| 319 (*str1)[os1->length]='\0'; | |
| 320 (*str2)[os2->length]='\0'; | |
| 321 ASN1_OCTET_STRING_free(os1); | |
| 322 ASN1_OCTET_STRING_free(os2); | |
| 323 return(1); | |
| 324 } | |
| 325 err: | |
| 326 return(0); | |
| 327 } | |
| 328 | |
| 329 | |
| OLD | NEW |