Ruby  1.9.3p448(2013-06-27revision41675)
ossl_x509req.c
Go to the documentation of this file.
1 /*
2  * $Id: ossl_x509req.c 32199 2011-06-22 08:41:08Z emboss $
3  * 'OpenSSL for Ruby' project
4  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5  * All rights reserved.
6  */
7 /*
8  * This program is licenced under the same licence as Ruby.
9  * (See the file 'LICENCE'.)
10  */
11 #include "ossl.h"
12 
13 #define WrapX509Req(klass, obj, req) do { \
14  if (!(req)) { \
15  ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \
16  } \
17  (obj) = Data_Wrap_Struct((klass), 0, X509_REQ_free, (req)); \
18 } while (0)
19 #define GetX509Req(obj, req) do { \
20  Data_Get_Struct((obj), X509_REQ, (req)); \
21  if (!(req)) { \
22  ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \
23  } \
24 } while (0)
25 #define SafeGetX509Req(obj, req) do { \
26  OSSL_Check_Kind((obj), cX509Req); \
27  GetX509Req((obj), (req)); \
28 } while (0)
29 
30 /*
31  * Classes
32  */
35 
36 /*
37  * Public functions
38  */
39 VALUE
40 ossl_x509req_new(X509_REQ *req)
41 {
42  X509_REQ *new;
43  VALUE obj;
44 
45  if (!req) {
46  new = X509_REQ_new();
47  } else {
48  new = X509_REQ_dup(req);
49  }
50  if (!new) {
52  }
53  WrapX509Req(cX509Req, obj, new);
54 
55  return obj;
56 }
57 
58 X509_REQ *
60 {
61  X509_REQ *req;
62 
63  SafeGetX509Req(obj, req);
64 
65  return req;
66 }
67 
68 X509_REQ *
70 {
71  X509_REQ *req, *new;
72 
73  SafeGetX509Req(obj, req);
74  if (!(new = X509_REQ_dup(req))) {
76  }
77 
78  return new;
79 }
80 
81 /*
82  * Private functions
83  */
84 static VALUE
86 {
87  X509_REQ *req;
88  VALUE obj;
89 
90  if (!(req = X509_REQ_new())) {
92  }
93  WrapX509Req(klass, obj, req);
94 
95  return obj;
96 }
97 
98 static VALUE
100 {
101  BIO *in;
102  X509_REQ *req, *x = DATA_PTR(self);
103  VALUE arg;
104 
105  if (rb_scan_args(argc, argv, "01", &arg) == 0) {
106  return self;
107  }
108  arg = ossl_to_der_if_possible(arg);
109  in = ossl_obj2bio(arg);
110  req = PEM_read_bio_X509_REQ(in, &x, NULL, NULL);
111  DATA_PTR(self) = x;
112  if (!req) {
113  OSSL_BIO_reset(in);
114  req = d2i_X509_REQ_bio(in, &x);
115  DATA_PTR(self) = x;
116  }
117  BIO_free(in);
118  if (!req) ossl_raise(eX509ReqError, NULL);
119 
120  return self;
121 }
122 
123 static VALUE
125 {
126  X509_REQ *a, *b, *req;
127 
128  rb_check_frozen(self);
129  if (self == other) return self;
130  GetX509Req(self, a);
131  SafeGetX509Req(other, b);
132  if (!(req = X509_REQ_dup(b))) {
134  }
135  X509_REQ_free(a);
136  DATA_PTR(self) = req;
137 
138  return self;
139 }
140 
141 static VALUE
143 {
144  X509_REQ *req;
145  BIO *out;
146  BUF_MEM *buf;
147  VALUE str;
148 
149  GetX509Req(self, req);
150  if (!(out = BIO_new(BIO_s_mem()))) {
152  }
153  if (!PEM_write_bio_X509_REQ(out, req)) {
154  BIO_free(out);
156  }
157  BIO_get_mem_ptr(out, &buf);
158  str = rb_str_new(buf->data, buf->length);
159  BIO_free(out);
160 
161  return str;
162 }
163 
164 static VALUE
166 {
167  X509_REQ *req;
168  VALUE str;
169  long len;
170  unsigned char *p;
171 
172  GetX509Req(self, req);
173  if ((len = i2d_X509_REQ(req, NULL)) <= 0)
175  str = rb_str_new(0, len);
176  p = (unsigned char *)RSTRING_PTR(str);
177  if (i2d_X509_REQ(req, &p) <= 0)
179  ossl_str_adjust(str, p);
180 
181  return str;
182 }
183 
184 static VALUE
186 {
187  X509_REQ *req;
188  BIO *out;
189  BUF_MEM *buf;
190  VALUE str;
191 
192  GetX509Req(self, req);
193  if (!(out = BIO_new(BIO_s_mem()))) {
195  }
196  if (!X509_REQ_print(out, req)) {
197  BIO_free(out);
199  }
200  BIO_get_mem_ptr(out, &buf);
201  str = rb_str_new(buf->data, buf->length);
202  BIO_free(out);
203 
204  return str;
205 }
206 
207 #if 0
208 /*
209  * Makes X509 from X509_REQuest
210  */
211 static VALUE
212 ossl_x509req_to_x509(VALUE self, VALUE days, VALUE key)
213 {
214  X509_REQ *req;
215  X509 *x509;
216 
217  GetX509Req(self, req);
218  ...
219  if (!(x509 = X509_REQ_to_X509(req, d, pkey))) {
220  ossl_raise(eX509ReqError, NULL);
221  }
222 
223  return ossl_x509_new(x509);
224 }
225 #endif
226 
227 static VALUE
229 {
230  X509_REQ *req;
231  long version;
232 
233  GetX509Req(self, req);
234  version = X509_REQ_get_version(req);
235 
236  return LONG2FIX(version);
237 }
238 
239 static VALUE
241 {
242  X509_REQ *req;
243  long ver;
244 
245  if ((ver = FIX2LONG(version)) < 0) {
246  ossl_raise(eX509ReqError, "version must be >= 0!");
247  }
248  GetX509Req(self, req);
249  if (!X509_REQ_set_version(req, ver)) {
251  }
252 
253  return version;
254 }
255 
256 static VALUE
258 {
259  X509_REQ *req;
260  X509_NAME *name;
261 
262  GetX509Req(self, req);
263  if (!(name = X509_REQ_get_subject_name(req))) { /* NO DUP - don't free */
265  }
266 
267  return ossl_x509name_new(name);
268 }
269 
270 static VALUE
272 {
273  X509_REQ *req;
274 
275  GetX509Req(self, req);
276  /* DUPs name */
277  if (!X509_REQ_set_subject_name(req, GetX509NamePtr(subject))) {
279  }
280 
281  return subject;
282 }
283 
284 static VALUE
286 {
287  X509_REQ *req;
288  BIO *out;
289  BUF_MEM *buf;
290  VALUE str;
291 
292  GetX509Req(self, req);
293 
294  if (!(out = BIO_new(BIO_s_mem()))) {
296  }
297  if (!i2a_ASN1_OBJECT(out, req->sig_alg->algorithm)) {
298  BIO_free(out);
300  }
301  BIO_get_mem_ptr(out, &buf);
302  str = rb_str_new(buf->data, buf->length);
303  BIO_free(out);
304  return str;
305 }
306 
307 static VALUE
309 {
310  X509_REQ *req;
311  EVP_PKEY *pkey;
312 
313  GetX509Req(self, req);
314  if (!(pkey = X509_REQ_get_pubkey(req))) { /* adds reference */
316  }
317 
318  return ossl_pkey_new(pkey); /* NO DUP - OK */
319 }
320 
321 static VALUE
323 {
324  X509_REQ *req;
325  EVP_PKEY *pkey;
326 
327  GetX509Req(self, req);
328  pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
329  if (!X509_REQ_set_pubkey(req, pkey)) {
331  }
332 
333  return key;
334 }
335 
336 static VALUE
337 ossl_x509req_sign(VALUE self, VALUE key, VALUE digest)
338 {
339  X509_REQ *req;
340  EVP_PKEY *pkey;
341  const EVP_MD *md;
342 
343  GetX509Req(self, req);
344  pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
345  md = GetDigestPtr(digest);
346  if (!X509_REQ_sign(req, pkey, md)) {
348  }
349 
350  return self;
351 }
352 
353 /*
354  * Checks that cert signature is made with PRIVversion of this PUBLIC 'key'
355  */
356 static VALUE
358 {
359  X509_REQ *req;
360  EVP_PKEY *pkey;
361  int i;
362 
363  GetX509Req(self, req);
364  pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
365  if ((i = X509_REQ_verify(req, pkey)) < 0) {
367  }
368  if (i > 0) {
369  return Qtrue;
370  }
371 
372  return Qfalse;
373 }
374 
375 static VALUE
377 {
378  X509_REQ *req;
379  int count, i;
380  X509_ATTRIBUTE *attr;
381  VALUE ary;
382 
383  GetX509Req(self, req);
384 
385  count = X509_REQ_get_attr_count(req);
386  if (count < 0) {
387  OSSL_Debug("count < 0???");
388  return rb_ary_new();
389  }
390  ary = rb_ary_new2(count);
391  for (i=0; i<count; i++) {
392  attr = X509_REQ_get_attr(req, i);
393  rb_ary_push(ary, ossl_x509attr_new(attr));
394  }
395 
396  return ary;
397 }
398 
399 static VALUE
401 {
402  X509_REQ *req;
403  X509_ATTRIBUTE *attr;
404  int i;
405  VALUE item;
406 
407  Check_Type(ary, T_ARRAY);
408  for (i=0;i<RARRAY_LEN(ary); i++) {
410  }
411  GetX509Req(self, req);
412  sk_X509_ATTRIBUTE_pop_free(req->req_info->attributes, X509_ATTRIBUTE_free);
413  req->req_info->attributes = NULL;
414  for (i=0;i<RARRAY_LEN(ary); i++) {
415  item = RARRAY_PTR(ary)[i];
416  attr = DupX509AttrPtr(item);
417  if (!X509_REQ_add1_attr(req, attr)) {
419  }
420  }
421  return ary;
422 }
423 
424 static VALUE
426 {
427  X509_REQ *req;
428 
429  GetX509Req(self, req);
430  if (!X509_REQ_add1_attr(req, DupX509AttrPtr(attr))) {
432  }
433 
434  return attr;
435 }
436 
437 /*
438  * X509_REQUEST init
439  */
440 void
442 {
444 
446 
450 
453  rb_define_alias(cX509Req, "to_s", "to_pem");
467 }
468 
469