example.c 7.9 KB

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