2
0

example.c 8.0 KB

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