Ruby  2.4.2p198(2017-09-14revision59899)
ossl_x509req.c
Go to the documentation of this file.
1 /*
2  * 'OpenSSL for Ruby' project
3  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
4  * All rights reserved.
5  */
6 /*
7  * This program is licensed under the same licence as Ruby.
8  * (See the file 'LICENCE'.)
9  */
10 #include "ossl.h"
11 
12 #define NewX509Req(klass) \
13  TypedData_Wrap_Struct((klass), &ossl_x509req_type, 0)
14 #define SetX509Req(obj, req) do { \
15  if (!(req)) { \
16  ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \
17  } \
18  RTYPEDDATA_DATA(obj) = (req); \
19 } while (0)
20 #define GetX509Req(obj, req) do { \
21  TypedData_Get_Struct((obj), X509_REQ, &ossl_x509req_type, (req)); \
22  if (!(req)) { \
23  ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \
24  } \
25 } while (0)
26 #define SafeGetX509Req(obj, req) do { \
27  OSSL_Check_Kind((obj), cX509Req); \
28  GetX509Req((obj), (req)); \
29 } while (0)
30 
31 /*
32  * Classes
33  */
36 
37 static void
39 {
40  X509_REQ_free(ptr);
41 }
42 
44  "OpenSSL/X509/REQ",
45  {
47  },
49 };
50 
51 /*
52  * Public functions
53  */
54 VALUE
55 ossl_x509req_new(X509_REQ *req)
56 {
57  X509_REQ *new;
58  VALUE obj;
59 
60  obj = NewX509Req(cX509Req);
61  if (!req) {
62  new = X509_REQ_new();
63  } else {
64  new = X509_REQ_dup(req);
65  }
66  if (!new) {
68  }
69  SetX509Req(obj, new);
70 
71  return obj;
72 }
73 
74 X509_REQ *
76 {
77  X509_REQ *req;
78 
79  SafeGetX509Req(obj, req);
80 
81  return req;
82 }
83 
84 X509_REQ *
86 {
87  X509_REQ *req, *new;
88 
89  SafeGetX509Req(obj, req);
90  if (!(new = X509_REQ_dup(req))) {
92  }
93 
94  return new;
95 }
96 
97 /*
98  * Private functions
99  */
100 static VALUE
102 {
103  X509_REQ *req;
104  VALUE obj;
105 
106  obj = NewX509Req(klass);
107  if (!(req = X509_REQ_new())) {
109  }
110  SetX509Req(obj, req);
111 
112  return obj;
113 }
114 
115 static VALUE
117 {
118  BIO *in;
119  X509_REQ *req, *x = DATA_PTR(self);
120  VALUE arg;
121 
122  if (rb_scan_args(argc, argv, "01", &arg) == 0) {
123  return self;
124  }
125  arg = ossl_to_der_if_possible(arg);
126  in = ossl_obj2bio(&arg);
127  req = PEM_read_bio_X509_REQ(in, &x, NULL, NULL);
128  DATA_PTR(self) = x;
129  if (!req) {
130  OSSL_BIO_reset(in);
131  req = d2i_X509_REQ_bio(in, &x);
132  DATA_PTR(self) = x;
133  }
134  BIO_free(in);
135  if (!req) ossl_raise(eX509ReqError, NULL);
136 
137  return self;
138 }
139 
140 static VALUE
142 {
143  X509_REQ *a, *b, *req;
144 
145  rb_check_frozen(self);
146  if (self == other) return self;
147  GetX509Req(self, a);
148  SafeGetX509Req(other, b);
149  if (!(req = X509_REQ_dup(b))) {
151  }
152  X509_REQ_free(a);
153  DATA_PTR(self) = req;
154 
155  return self;
156 }
157 
158 static VALUE
160 {
161  X509_REQ *req;
162  BIO *out;
163 
164  GetX509Req(self, req);
165  if (!(out = BIO_new(BIO_s_mem()))) {
167  }
168  if (!PEM_write_bio_X509_REQ(out, req)) {
169  BIO_free(out);
171  }
172 
173  return ossl_membio2str(out);
174 }
175 
176 static VALUE
178 {
179  X509_REQ *req;
180  VALUE str;
181  long len;
182  unsigned char *p;
183 
184  GetX509Req(self, req);
185  if ((len = i2d_X509_REQ(req, NULL)) <= 0)
187  str = rb_str_new(0, len);
188  p = (unsigned char *)RSTRING_PTR(str);
189  if (i2d_X509_REQ(req, &p) <= 0)
191  ossl_str_adjust(str, p);
192 
193  return str;
194 }
195 
196 static VALUE
198 {
199  X509_REQ *req;
200  BIO *out;
201 
202  GetX509Req(self, req);
203  if (!(out = BIO_new(BIO_s_mem()))) {
205  }
206  if (!X509_REQ_print(out, req)) {
207  BIO_free(out);
209  }
210 
211  return ossl_membio2str(out);
212 }
213 
214 #if 0
215 /*
216  * Makes X509 from X509_REQuest
217  */
218 static VALUE
219 ossl_x509req_to_x509(VALUE self, VALUE days, VALUE key)
220 {
221  X509_REQ *req;
222  X509 *x509;
223 
224  GetX509Req(self, req);
225  ...
226  if (!(x509 = X509_REQ_to_X509(req, d, pkey))) {
228  }
229 
230  return ossl_x509_new(x509);
231 }
232 #endif
233 
234 static VALUE
236 {
237  X509_REQ *req;
238  long version;
239 
240  GetX509Req(self, req);
241  version = X509_REQ_get_version(req);
242 
243  return LONG2NUM(version);
244 }
245 
246 static VALUE
248 {
249  X509_REQ *req;
250  long ver;
251 
252  if ((ver = NUM2LONG(version)) < 0) {
253  ossl_raise(eX509ReqError, "version must be >= 0!");
254  }
255  GetX509Req(self, req);
256  if (!X509_REQ_set_version(req, ver)) {
257  ossl_raise(eX509ReqError, "X509_REQ_set_version");
258  }
259 
260  return version;
261 }
262 
263 static VALUE
265 {
266  X509_REQ *req;
267  X509_NAME *name;
268 
269  GetX509Req(self, req);
270  if (!(name = X509_REQ_get_subject_name(req))) { /* NO DUP - don't free */
272  }
273 
274  return ossl_x509name_new(name);
275 }
276 
277 static VALUE
279 {
280  X509_REQ *req;
281 
282  GetX509Req(self, req);
283  /* DUPs name */
284  if (!X509_REQ_set_subject_name(req, GetX509NamePtr(subject))) {
286  }
287 
288  return subject;
289 }
290 
291 static VALUE
293 {
294  X509_REQ *req;
295  const X509_ALGOR *alg;
296  BIO *out;
297 
298  GetX509Req(self, req);
299 
300  if (!(out = BIO_new(BIO_s_mem()))) {
302  }
303  X509_REQ_get0_signature(req, NULL, &alg);
304  if (!i2a_ASN1_OBJECT(out, alg->algorithm)) {
305  BIO_free(out);
307  }
308 
309  return ossl_membio2str(out);
310 }
311 
312 static VALUE
314 {
315  X509_REQ *req;
316  EVP_PKEY *pkey;
317 
318  GetX509Req(self, req);
319  if (!(pkey = X509_REQ_get_pubkey(req))) { /* adds reference */
321  }
322 
323  return ossl_pkey_new(pkey); /* NO DUP - OK */
324 }
325 
326 static VALUE
328 {
329  X509_REQ *req;
330  EVP_PKEY *pkey;
331 
332  GetX509Req(self, req);
333  pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
334  if (!X509_REQ_set_pubkey(req, pkey)) {
336  }
337 
338  return key;
339 }
340 
341 static VALUE
343 {
344  X509_REQ *req;
345  EVP_PKEY *pkey;
346  const EVP_MD *md;
347 
348  GetX509Req(self, req);
349  pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
350  md = GetDigestPtr(digest);
351  if (!X509_REQ_sign(req, pkey, md)) {
353  }
354 
355  return self;
356 }
357 
358 /*
359  * Checks that cert signature is made with PRIVversion of this PUBLIC 'key'
360  */
361 static VALUE
363 {
364  X509_REQ *req;
365  EVP_PKEY *pkey;
366 
367  GetX509Req(self, req);
368  pkey = GetPKeyPtr(key); /* NO NEED TO DUP */
369  switch (X509_REQ_verify(req, pkey)) {
370  case 1:
371  return Qtrue;
372  case 0:
374  return Qfalse;
375  default:
377  }
378 }
379 
380 static VALUE
382 {
383  X509_REQ *req;
384  int count, i;
385  X509_ATTRIBUTE *attr;
386  VALUE ary;
387 
388  GetX509Req(self, req);
389 
390  count = X509_REQ_get_attr_count(req);
391  if (count < 0) {
392  OSSL_Debug("count < 0???");
393  return rb_ary_new();
394  }
395  ary = rb_ary_new2(count);
396  for (i=0; i<count; i++) {
397  attr = X509_REQ_get_attr(req, i);
398  rb_ary_push(ary, ossl_x509attr_new(attr));
399  }
400 
401  return ary;
402 }
403 
404 static VALUE
406 {
407  X509_REQ *req;
408  X509_ATTRIBUTE *attr;
409  long i;
410  VALUE item;
411 
412  Check_Type(ary, T_ARRAY);
413  for (i=0;i<RARRAY_LEN(ary); i++) {
415  }
416  GetX509Req(self, req);
417  while ((attr = X509_REQ_delete_attr(req, 0)))
418  X509_ATTRIBUTE_free(attr);
419  for (i=0;i<RARRAY_LEN(ary); i++) {
420  item = RARRAY_AREF(ary, i);
421  attr = GetX509AttrPtr(item);
422  if (!X509_REQ_add1_attr(req, attr)) {
424  }
425  }
426  return ary;
427 }
428 
429 static VALUE
431 {
432  X509_REQ *req;
433 
434  GetX509Req(self, req);
435  if (!X509_REQ_add1_attr(req, GetX509AttrPtr(attr))) {
437  }
438 
439  return attr;
440 }
441 
442 /*
443  * X509_REQUEST init
444  */
445 void
447 {
448 #if 0
449  mOSSL = rb_define_module("OpenSSL");
452 #endif
453 
455 
457 
461 
464  rb_define_alias(cX509Req, "to_s", "to_pem");
478 }
static VALUE ossl_x509req_set_attributes(VALUE self, VALUE ary)
Definition: ossl_x509req.c:405
VALUE rb_eStandardError
Definition: error.c:760
VALUE mOSSL
Definition: ossl.c:213
#define RARRAY_LEN(a)
Definition: ruby.h:1026
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1145
static VALUE ossl_x509req_add_attribute(VALUE self, VALUE attr)
Definition: ossl_x509req.c:430
int count
Definition: encoding.c:56
#define Qtrue
Definition: ruby.h:437
void Init_ossl_x509req(void)
Definition: ossl_x509req.c:446
static VALUE ossl_x509req_initialize(int argc, VALUE *argv, VALUE self)
Definition: ossl_x509req.c:116
EVP_PKEY * GetPrivPKeyPtr(VALUE obj)
Definition: ossl_pkey.c:216
#define ossl_str_adjust(str, p)
Definition: ossl.h:82
static VALUE ossl_x509req_set_public_key(VALUE self, VALUE key)
Definition: ossl_x509req.c:327
static VALUE ossl_x509req_alloc(VALUE klass)
Definition: ossl_x509req.c:101
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:905
static VALUE ossl_x509req_copy(VALUE self, VALUE other)
Definition: ossl_x509req.c:141
BIO * ossl_obj2bio(volatile VALUE *pobj)
Definition: ossl_bio.c:13
X509_ATTRIBUTE * GetX509AttrPtr(VALUE)
Definition: ossl_x509attr.c:75
static VALUE ossl_x509req_get_subject(VALUE self)
Definition: ossl_x509req.c:264
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:693
#define Check_Type(v, t)
Definition: ruby.h:562
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE cX509Req
Definition: ossl_x509req.c:34
#define DATA_PTR(dta)
Definition: ruby.h:1113
#define T_ARRAY
Definition: ruby.h:498
static VALUE ossl_x509req_to_pem(VALUE self)
Definition: ossl_x509req.c:159
static void ossl_x509req_free(void *ptr)
Definition: ossl_x509req.c:38
#define SafeGetX509Req(obj, req)
Definition: ossl_x509req.c:26
VALUE ossl_membio2str(BIO *bio)
Definition: ossl_bio.c:47
VALUE ossl_pkey_new(EVP_PKEY *pkey)
Definition: ossl_pkey.c:107
X509_NAME * GetX509NamePtr(VALUE)
Definition: ossl_x509name.c:80
static VALUE ossl_x509req_get_public_key(VALUE self)
Definition: ossl_x509req.c:313
#define rb_ary_new2
Definition: intern.h:90
VALUE eX509ReqError
Definition: ossl_x509req.c:35
#define rb_define_copy_func(klass, func)
Definition: ruby_missing.h:13
VALUE ossl_to_der_if_possible(VALUE obj)
Definition: ossl.c:237
#define X509_REQ_get0_signature
void ossl_clear_error(void)
Definition: ossl.c:289
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1872
static VALUE ossl_x509req_get_signature_algorithm(VALUE self)
Definition: ossl_x509req.c:292
VALUE rb_ary_new(void)
Definition: array.c:493
#define OSSL_BIO_reset(bio)
Definition: ossl.h:110
const EVP_MD * GetDigestPtr(VALUE obj)
Definition: ossl_digest.c:49
VALUE eOSSLError
Definition: ossl.c:218
int argc
Definition: ruby.c:183
#define Qfalse
Definition: ruby.h:436
VALUE ossl_x509_new(X509 *)
Definition: ossl_x509cert.c:55
static VALUE ossl_x509req_to_text(VALUE self)
Definition: ossl_x509req.c:197
#define NewX509Req(klass)
Definition: ossl_x509req.c:12
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1758
static VALUE ossl_x509req_verify(VALUE self, VALUE key)
Definition: ossl_x509req.c:362
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1919
unsigned long VALUE
Definition: ruby.h:85
static VALUE ossl_x509req_sign(VALUE self, VALUE key, VALUE digest)
Definition: ossl_x509req.c:342
X509_REQ * DupX509ReqPtr(VALUE obj)
Definition: ossl_x509req.c:85
VALUE mX509
Definition: ossl_x509.c:12
#define OSSL_Debug
Definition: ossl.h:155
#define LONG2NUM(x)
Definition: ruby.h:1573
register unsigned int len
Definition: zonetab.h:51
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:790
static VALUE ossl_x509req_get_attributes(VALUE self)
Definition: ossl_x509req.c:381
#define RSTRING_PTR(str)
Definition: ruby.h:982
VALUE ossl_x509attr_new(X509_ATTRIBUTE *)
Definition: ossl_x509attr.c:55
#define RARRAY_AREF(a, i)
Definition: ruby.h:1040
#define OSSL_Check_Kind(obj, klass)
Definition: ossl.h:52
#define GetX509Req(obj, req)
Definition: ossl_x509req.c:20
X509_REQ * GetX509ReqPtr(VALUE obj)
Definition: ossl_x509req.c:75
static const rb_data_type_t ossl_x509req_type
Definition: ossl_x509req.c:43
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:278
EVP_PKEY * GetPKeyPtr(VALUE obj)
Definition: ossl_pkey.c:206
const char * name
Definition: nkf.c:208
static VALUE ossl_x509req_set_version(VALUE self, VALUE version)
Definition: ossl_x509req.c:247
static VALUE ossl_x509req_set_subject(VALUE self, VALUE subject)
Definition: ossl_x509req.c:278
VALUE ossl_x509name_new(X509_NAME *)
Definition: ossl_x509name.c:60
#define rb_check_frozen(obj)
Definition: intern.h:276
static VALUE ossl_x509req_get_version(VALUE self)
Definition: ossl_x509req.c:235
VALUE rb_define_module(const char *name)
Definition: class.c:768
#define NULL
Definition: _sdbm.c:102
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
VALUE ossl_x509req_new(X509_REQ *req)
Definition: ossl_x509req.c:55
#define SetX509Req(obj, req)
Definition: ossl_x509req.c:14
int version
Definition: ossl_ssl.c:55
static VALUE ossl_x509req_to_der(VALUE self)
Definition: ossl_x509req.c:177
#define NUM2LONG(x)
Definition: ruby.h:648
VALUE cX509Attr
Definition: ossl_x509attr.c:34
char ** argv
Definition: ruby.c:184
VALUE rb_str_new(const char *, long)
Definition: string.c:736