Ruby 2.0.0p353(2013-11-22revision43784)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

ossl.c
Go to the documentation of this file.
1 /*
2 * $Id: ossl.c 39584 2013-03-04 15:17:27Z nagachika $
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 #include <stdarg.h> /* for ossl_raise */
13
14 /*
15 * String to HEXString conversion
16 */
17 int
18 string2hex(const unsigned char *buf, int buf_len, char **hexbuf, int *hexbuf_len)
19 {
20 static const char hex[]="0123456789abcdef";
21 int i, len = 2 * buf_len;
22
23 if (buf_len < 0 || len < buf_len) { /* PARANOIA? */
24 return -1;
25 }
26 if (!hexbuf) { /* if no buf, return calculated len */
27 if (hexbuf_len) {
28 *hexbuf_len = len;
29 }
30 return len;
31 }
32 if (!(*hexbuf = OPENSSL_malloc(len + 1))) {
33 return -1;
34 }
35 for (i = 0; i < buf_len; i++) {
36 (*hexbuf)[2 * i] = hex[((unsigned char)buf[i]) >> 4];
37 (*hexbuf)[2 * i + 1] = hex[buf[i] & 0x0f];
38 }
39 (*hexbuf)[2 * i] = '\0';
40
41 if (hexbuf_len) {
42 *hexbuf_len = len;
43 }
44 return len;
45 }
46
47 /*
48 * Data Conversion
49 */
50 #define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \
51 STACK_OF(type) * \
52 ossl_##name##_ary2sk0(VALUE ary) \
53 { \
54 STACK_OF(type) *sk; \
55 VALUE val; \
56 type *x; \
57 int i; \
58 \
59 Check_Type(ary, T_ARRAY); \
60 sk = sk_##type##_new_null(); \
61 if (!sk) ossl_raise(eOSSLError, NULL); \
62 \
63 for (i = 0; i < RARRAY_LEN(ary); i++) { \
64 val = rb_ary_entry(ary, i); \
65 if (!rb_obj_is_kind_of(val, expected_class)) { \
66 sk_##type##_pop_free(sk, type##_free); \
67 ossl_raise(eOSSLError, "object in array not" \
68 " of class ##type##"); \
69 } \
70 x = dup(val); /* NEED TO DUP */ \
71 sk_##type##_push(sk, x); \
72 } \
73 return sk; \
74 } \
75 \
76 STACK_OF(type) * \
77 ossl_protect_##name##_ary2sk(VALUE ary, int *status) \
78 { \
79 return (STACK_OF(type)*)rb_protect( \
80 (VALUE(*)_((VALUE)))ossl_##name##_ary2sk0, \
81 ary, \
82 status); \
83 } \
84 \
85 STACK_OF(type) * \
86 ossl_##name##_ary2sk(VALUE ary) \
87 { \
88 STACK_OF(type) *sk; \
89 int status = 0; \
90 \
91 sk = ossl_protect_##name##_ary2sk(ary, &status); \
92 if (status) rb_jump_tag(status); \
93 \
94 return sk; \
95 }
96 OSSL_IMPL_ARY2SK(x509, X509, cX509Cert, DupX509CertPtr)
97
98 #define OSSL_IMPL_SK2ARY(name, type) \
99 VALUE \
100 ossl_##name##_sk2ary(STACK_OF(type) *sk) \
101 { \
102 type *t; \
103 int i, num; \
104 VALUE ary; \
105 \
106 if (!sk) { \
107 OSSL_Debug("empty sk!"); \
108 return Qnil; \
109 } \
110 num = sk_##type##_num(sk); \
111 if (num < 0) { \
112 OSSL_Debug("items in sk < -1???"); \
113 return rb_ary_new(); \
114 } \
115 ary = rb_ary_new2(num); \
116 \
117 for (i=0; i<num; i++) { \
118 t = sk_##type##_value(sk, i); \
119 rb_ary_push(ary, ossl_##name##_new(t)); \
120 } \
121 return ary; \
122 }
123 OSSL_IMPL_SK2ARY(x509, X509)
124 OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
125 OSSL_IMPL_SK2ARY(x509name, X509_NAME)
126
127 static VALUE
128 ossl_str_new(int size)
129 {
130 return rb_str_new(0, size);
131 }
132
133 VALUE
134 ossl_buf2str(char *buf, int len)
135 {
136 VALUE str;
137 int status = 0;
138
139 str = rb_protect((VALUE(*)_((VALUE)))ossl_str_new, len, &status);
140 if(!NIL_P(str)) memcpy(RSTRING_PTR(str), buf, len);
141 OPENSSL_free(buf);
142 if(status) rb_jump_tag(status);
143
144 return str;
145 }
146
147 /*
148 * our default PEM callback
149 */
150 static VALUE
151 ossl_pem_passwd_cb0(VALUE flag)
152 {
153 VALUE pass;
154
155 pass = rb_yield(flag);
156 SafeStringValue(pass);
157
158 return pass;
159 }
160
161 int
162 ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd)
163 {
164 int len, status = 0;
165 VALUE rflag, pass;
166
167 if (pwd || !rb_block_given_p())
168 return PEM_def_callback(buf, max_len, flag, pwd);
169
170 while (1) {
171 /*
172 * when the flag is nonzero, this passphrase
173 * will be used to perform encryption; otherwise it will
174 * be used to perform decryption.
175 */
176 rflag = flag ? Qtrue : Qfalse;
177 pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status);
178 if (status) {
179 /* ignore an exception raised. */
180 rb_set_errinfo(Qnil);
181 return -1;
182 }
183 len = RSTRING_LENINT(pass);
184 if (len < 4) { /* 4 is OpenSSL hardcoded limit */
185 rb_warning("password must be longer than 4 bytes");
186 continue;
187 }
188 if (len > max_len) {
189 rb_warning("password must be shorter then %d bytes", max_len-1);
190 continue;
191 }
192 memcpy(buf, RSTRING_PTR(pass), len);
193 break;
194 }
195 return len;
196 }
197
198 /*
199 * Verify callback
200 */
201 int ossl_verify_cb_idx;
202
203 VALUE
204 ossl_call_verify_cb_proc(struct ossl_verify_cb_args *args)
205 {
206 return rb_funcall(args->proc, rb_intern("call"), 2,
207 args->preverify_ok, args->store_ctx);
208 }
209
210 int
211 ossl_verify_cb(int ok, X509_STORE_CTX *ctx)
212 {
213 VALUE proc, rctx, ret;
214 struct ossl_verify_cb_args args;
215 int state = 0;
216
217 proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, ossl_verify_cb_idx);
218 if ((void*)proc == 0)
219 proc = (VALUE)X509_STORE_get_ex_data(ctx->ctx, ossl_verify_cb_idx);
220 if ((void*)proc == 0)
221 return ok;
222 if (!NIL_P(proc)) {
223 ret = Qfalse;
224 rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new,
225 (VALUE)ctx, &state);
226 if (state) {
227 rb_set_errinfo(Qnil);
228 rb_warn("StoreContext initialization failure");
229 }
230 else {
231 args.proc = proc;
232 args.preverify_ok = ok ? Qtrue : Qfalse;
233 args.store_ctx = rctx;
234 ret = rb_protect((VALUE(*)(VALUE))ossl_call_verify_cb_proc, (VALUE)&args, &state);
235 if (state) {
236 rb_set_errinfo(Qnil);
237 rb_warn("exception in verify_callback is ignored");
238 }
239 ossl_x509stctx_clear_ptr(rctx);
240 }
241 if (ret == Qtrue) {
242 X509_STORE_CTX_set_error(ctx, X509_V_OK);
243 ok = 1;
244 }
245 else{
246 if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) {
247 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
248 }
249 ok = 0;
250 }
251 }
252
253 return ok;
254 }
255
256 /*
257 * main module
258 */
259 VALUE mOSSL;
260
261 /*
262 * OpenSSLError < StandardError
263 */
264 VALUE eOSSLError;
265
266 /*
267 * Convert to DER string
268 */
269 ID ossl_s_to_der;
270
271 VALUE
272 ossl_to_der(VALUE obj)
273 {
274 VALUE tmp;
275
276 tmp = rb_funcall(obj, ossl_s_to_der, 0);
277 StringValue(tmp);
278
279 return tmp;
280 }
281
282 VALUE
283 ossl_to_der_if_possible(VALUE obj)
284 {
285 if(rb_respond_to(obj, ossl_s_to_der))
286 return ossl_to_der(obj);
287 return obj;
288 }
289
290 /*
291 * Errors
292 */
293 static VALUE
294 ossl_make_error(VALUE exc, const char *fmt, va_list args)
295 {
296 char buf[BUFSIZ];
297 const char *msg;
298 long e;
299 int len = 0;
300
301 #ifdef HAVE_ERR_PEEK_LAST_ERROR
302 e = ERR_peek_last_error();
303 #else
304 e = ERR_peek_error();
305 #endif
306 if (fmt) {
307 len = vsnprintf(buf, BUFSIZ, fmt, args);
308 }
309 if (len < BUFSIZ && e) {
310 if (dOSSL == Qtrue) /* FULL INFO */
311 msg = ERR_error_string(e, NULL);
312 else
313 msg = ERR_reason_error_string(e);
314 len += snprintf(buf+len, BUFSIZ-len, "%s%s", (len ? ": " : ""), msg);
315 }
316 if (dOSSL == Qtrue){ /* show all errors on the stack */
317 while ((e = ERR_get_error()) != 0){
318 rb_warn("error on stack: %s", ERR_error_string(e, NULL));
319 }
320 }
321 ERR_clear_error();
322
323 if(len > BUFSIZ) len = rb_long2int(strlen(buf));
324 return rb_exc_new(exc, buf, len);
325 }
326
327 void
328 ossl_raise(VALUE exc, const char *fmt, ...)
329 {
330 va_list args;
331 VALUE err;
332 va_start(args, fmt);
333 err = ossl_make_error(exc, fmt, args);
334 va_end(args);
335 rb_exc_raise(err);
336 }
337
338 VALUE
339 ossl_exc_new(VALUE exc, const char *fmt, ...)
340 {
341 va_list args;
342 VALUE err;
343 va_start(args, fmt);
344 err = ossl_make_error(exc, fmt, args);
345 va_end(args);
346 return err;
347 }
348
349 /*
350 * call-seq:
351 * OpenSSL.errors -> [String...]
352 *
353 * See any remaining errors held in queue.
354 *
355 * Any errors you see here are probably due to a bug in ruby's OpenSSL implementation.
356 */
357 VALUE
358 ossl_get_errors()
359 {
360 VALUE ary;
361 long e;
362
363 ary = rb_ary_new();
364 while ((e = ERR_get_error()) != 0){
365 rb_ary_push(ary, rb_str_new2(ERR_error_string(e, NULL)));
366 }
367
368 return ary;
369 }
370
371 /*
372 * Debug
373 */
374 VALUE dOSSL;
375
376 #if !defined(HAVE_VA_ARGS_MACRO)
377 void
378 ossl_debug(const char *fmt, ...)
379 {
380 va_list args;
381
382 if (dOSSL == Qtrue) {
383 fprintf(stderr, "OSSL_DEBUG: ");
384 va_start(args, fmt);
385 vfprintf(stderr, fmt, args);
386 va_end(args);
387 fprintf(stderr, " [CONTEXT N/A]\n");
388 }
389 }
390 #endif
391
392 /*
393 * call-seq:
394 * OpenSSL.debug -> true | false
395 */
396 static VALUE
397 ossl_debug_get(VALUE self)
398 {
399 return dOSSL;
400 }
401
402 /*
403 * call-seq:
404 * OpenSSL.debug = boolean -> boolean
405 *
406 * Turns on or off CRYPTO_MEM_CHECK.
407 * Also shows some debugging message on stderr.
408 */
409 static VALUE
410 ossl_debug_set(VALUE self, VALUE val)
411 {
412 VALUE old = dOSSL;
413 dOSSL = val;
414
415 if (old != dOSSL) {
416 if (dOSSL == Qtrue) {
417 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
418 fprintf(stderr, "OSSL_DEBUG: IS NOW ON!\n");
419 } else if (old == Qtrue) {
420 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
421 fprintf(stderr, "OSSL_DEBUG: IS NOW OFF!\n");
422 }
423 }
424 return val;
425 }
426
427 /*
428 * call-seq:
429 * OpenSSL.fips_mode = boolean -> boolean
430 *
431 * Turns FIPS mode on or off. Turning on FIPS mode will obviously only have an
432 * effect for FIPS-capable installations of the OpenSSL library. Trying to do
433 * so otherwise will result in an error.
434 *
435 * === Examples
436 *
437 * OpenSSL.fips_mode = true # turn FIPS mode on
438 * OpenSSL.fips_mode = false # and off again
439 */
440 static VALUE
441 ossl_fips_mode_set(VALUE self, VALUE enabled)
442 {
443
444 #ifdef HAVE_OPENSSL_FIPS
445 if (RTEST(enabled)) {
446 int mode = FIPS_mode();
447 if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */
448 ossl_raise(eOSSLError, "Turning on FIPS mode failed");
449 } else {
450 if(!FIPS_mode_set(0)) /* turning off twice is OK */
451 ossl_raise(eOSSLError, "Turning off FIPS mode failed");
452 }
453 return enabled;
454 #else
455 if (RTEST(enabled))
456 ossl_raise(eOSSLError, "This version of OpenSSL does not support FIPS mode");
457 return enabled;
458 #endif
459 }
460
461 /*
462 * OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
463 * OpenSSL[http://www.openssl.org/] library.
464 *
465 * = Examples
466 *
467 * All examples assume you have loaded OpenSSL with:
468 *
469 * require 'openssl'
470 *
471 * These examples build atop each other. For example the key created in the
472 * next is used in throughout these examples.
473 *
474 * == Keys
475 *
476 * === Creating a Key
477 *
478 * This example creates a 2048 bit RSA keypair and writes it to the current
479 * directory.
480 *
481 * key = OpenSSL::PKey::RSA.new 2048
482 *
483 * open 'private_key.pem', 'w' do |io| io.write key.to_pem end
484 * open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end
485 *
486 * === Exporting a Key
487 *
488 * Keys saved to disk without encryption are not secure as anyone who gets
489 * ahold of the key may use it unless it is encrypted. In order to securely
490 * export a key you may export it with a pass phrase.
491 *
492 * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
493 * pass_phrase = 'my secure pass phrase goes here'
494 *
495 * key_secure = key.export cipher, pass_phrase
496 *
497 * open 'private.secure.pem', 'w' do |io|
498 * io.write key_secure
499 * end
500 *
501 * OpenSSL::Cipher.ciphers returns a list of available ciphers.
502 *
503 * === Loading a Key
504 *
505 * A key can also be loaded from a file.
506 *
507 * key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
508 * key2.public? # => true
509 *
510 * or
511 *
512 * key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
513 * key3.private? # => false
514 *
515 * === Loading an Encrypted Key
516 *
517 * OpenSSL will prompt you for your pass phrase when loading an encrypted key.
518 * If you will not be able to type in the pass phrase you may provide it when
519 * loading the key:
520 *
521 * key4_pem = File.read 'private.secure.pem'
522 * key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
523 *
524 * == RSA Encryption
525 *
526 * RSA provides encryption and decryption using the public and private keys.
527 * You can use a variety of padding methods depending upon the intended use of
528 * encrypted data.
529 *
530 * === Encryption & Decryption
531 *
532 * Asymmetric public/private key encryption is slow and victim to attack in
533 * cases where it is used without padding or directly to encrypt larger chunks
534 * of data. Typical use cases for RSA encryption involve "wrapping" a symmetric
535 * key with the public key of the recipient who would "unwrap" that symmetric
536 * key again using their private key.
537 * The following illustrates a simplified example of such a key transport
538 * scheme. It shouldn't be used in practice, though, standardized protocols
539 * should always be preferred.
540 *
541 * wrapped_key = key.public_encrypt key
542 *
543 * A symmetric key encrypted with the public key can only be decrypted with
544 * the corresponding private key of the recipient.
545 *
546 * original_key = key.private_decrypt wrapped_key
547 *
548 * By default PKCS#1 padding will be used, but it is also possible to use
549 * other forms of padding, see PKey::RSA for further details.
550 *
551 * === Signatures
552 *
553 * Using "private_encrypt" to encrypt some data with the private key is
554 * equivalent to applying a digital signature to the data. A verifying
555 * party may validate the signature by comparing the result of decrypting
556 * the signature with "public_decrypt" to the original data. However,
557 * OpenSSL::PKey already has methods "sign" and "verify" that handle
558 * digital signatures in a standardized way - "private_encrypt" and
559 * "public_decrypt" shouldn't be used in practice.
560 *
561 * To sign a document, a cryptographically secure hash of the document is
562 * computed first, which is then signed using the private key.
563 *
564 * digest = OpenSSL::Digest::SHA256.new
565 * signature = key.sign digest, document
566 *
567 * To validate the signature, again a hash of the document is computed and
568 * the signature is decrypted using the public key. The result is then
569 * compared to the hash just computed, if they are equal the signature was
570 * valid.
571 *
572 * digest = OpenSSL::Digest::SHA256.new
573 * if key.verify digest, signature, document
574 * puts 'Valid'
575 * else
576 * puts 'Invalid'
577 * end
578 *
579 * == PBKDF2 Password-based Encryption
580 *
581 * If supported by the underlying OpenSSL version used, Password-based
582 * Encryption should use the features of PKCS5. If not supported or if
583 * required by legacy applications, the older, less secure methods specified
584 * in RFC 2898 are also supported (see below).
585 *
586 * PKCS5 supports PBKDF2 as it was specified in PKCS#5
587 * v2.0[http://www.rsa.com/rsalabs/node.asp?id=2127]. It still uses a
588 * password, a salt, and additionally a number of iterations that will
589 * slow the key derivation process down. The slower this is, the more work
590 * it requires being able to brute-force the resulting key.
591 *
592 * === Encryption
593 *
594 * The strategy is to first instantiate a Cipher for encryption, and
595 * then to generate a random IV plus a key derived from the password
596 * using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt,
597 * the number of iterations largely depends on the hardware being used.
598 *
599 * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
600 * cipher.encrypt
601 * iv = cipher.random_iv
602 *
603 * pwd = 'some hopefully not to easily guessable password'
604 * salt = OpenSSL::Random.random_bytes 16
605 * iter = 20000
606 * key_len = cipher.key_len
607 * digest = OpenSSL::Digest::SHA256.new
608 *
609 * key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
610 * cipher.key = key
611 *
612 * Now encrypt the data:
613 *
614 * encrypted = cipher.update document
615 * encrypted << cipher.final
616 *
617 * === Decryption
618 *
619 * Use the same steps as before to derive the symmetric AES key, this time
620 * setting the Cipher up for decryption.
621 *
622 * cipher = OpenSSL::Cipher.new 'AES-128-CBC'
623 * cipher.decrypt
624 * cipher.iv = iv # the one generated with #random_iv
625 *
626 * pwd = 'some hopefully not to easily guessable password'
627 * salt = ... # the one generated above
628 * iter = 20000
629 * key_len = cipher.key_len
630 * digest = OpenSSL::Digest::SHA256.new
631 *
632 * key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
633 * cipher.key = key
634 *
635 * Now decrypt the data:
636 *
637 * decrypted = cipher.update encrypted
638 * decrypted << cipher.final
639 *
640 * == PKCS #5 Password-based Encryption
641 *
642 * PKCS #5 is a password-based encryption standard documented at
643 * RFC2898[http://www.ietf.org/rfc/rfc2898.txt]. It allows a short password or
644 * passphrase to be used to create a secure encryption key. If possible, PBKDF2
645 * as described above should be used if the circumstances allow it.
646 *
647 * PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption
648 * key.
649 *
650 * pass_phrase = 'my secure pass phrase goes here'
651 * salt = '8 octets'
652 *
653 * === Encryption
654 *
655 * First set up the cipher for encryption
656 *
657 * encrypter = OpenSSL::Cipher.new 'AES-128-CBC'
658 * encrypter.encrypt
659 * encrypter.pkcs5_keyivgen pass_phrase, salt
660 *
661 * Then pass the data you want to encrypt through
662 *
663 * encrypted = encrypter.update 'top secret document'
664 * encrypted << encrypter.final
665 *
666 * === Decryption
667 *
668 * Use a new Cipher instance set up for decryption
669 *
670 * decrypter = OpenSSL::Cipher.new 'AES-128-CBC'
671 * decrypter.decrypt
672 * decrypter.pkcs5_keyivgen pass_phrase, salt
673 *
674 * Then pass the data you want to decrypt through
675 *
676 * plain = decrypter.update encrypted
677 * plain << decrypter.final
678 *
679 * == X509 Certificates
680 *
681 * === Creating a Certificate
682 *
683 * This example creates a self-signed certificate using an RSA key and a SHA1
684 * signature.
685 *
686 * name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
687 *
688 * cert = OpenSSL::X509::Certificate.new
689 * cert.version = 2
690 * cert.serial = 0
691 * cert.not_before = Time.now
692 * cert.not_after = Time.now + 3600
693 *
694 * cert.public_key = key.public_key
695 * cert.subject = name
696 *
697 * === Certificate Extensions
698 *
699 * You can add extensions to the certificate with
700 * OpenSSL::SSL::ExtensionFactory to indicate the purpose of the certificate.
701 *
702 * extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert
703 *
704 * cert.add_extension \
705 * extension_factory.create_extension('basicConstraints', 'CA:FALSE', true)
706 *
707 * cert.add_extension \
708 * extension_factory.create_extension(
709 * 'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature')
710 *
711 * cert.add_extension \
712 * extension_factory.create_extension('subjectKeyIdentifier', 'hash')
713 *
714 * The list of supported extensions (and in some cases their possible values)
715 * can be derived from the "objects.h" file in the OpenSSL source code.
716 *
717 * === Signing a Certificate
718 *
719 * To sign a certificate set the issuer and use OpenSSL::X509::Certificate#sign
720 * with a digest algorithm. This creates a self-signed cert because we're using
721 * the same name and key to sign the certificate as was used to create the
722 * certificate.
723 *
724 * cert.issuer = name
725 * cert.sign key, OpenSSL::Digest::SHA1.new
726 *
727 * open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
728 *
729 * === Loading a Certificate
730 *
731 * Like a key, a cert can also be loaded from a file.
732 *
733 * cert2 = OpenSSL::X509::Certificate.new File.read 'certificate.pem'
734 *
735 * === Verifying a Certificate
736 *
737 * Certificate#verify will return true when a certificate was signed with the
738 * given public key.
739 *
740 * raise 'certificate can not be verified' unless cert2.verify key
741 *
742 * == Certificate Authority
743 *
744 * A certificate authority (CA) is a trusted third party that allows you to
745 * verify the ownership of unknown certificates. The CA issues key signatures
746 * that indicate it trusts the user of that key. A user encountering the key
747 * can verify the signature by using the CA's public key.
748 *
749 * === CA Key
750 *
751 * CA keys are valuable, so we encrypt and save it to disk and make sure it is
752 * not readable by other users.
753 *
754 * ca_key = OpenSSL::PKey::RSA.new 2048
755 *
756 * cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
757 *
758 * open 'ca_key.pem', 'w', 0400 do |io|
759 * io.write key.export(cipher, pass_phrase)
760 * end
761 *
762 * === CA Certificate
763 *
764 * A CA certificate is created the same way we created a certificate above, but
765 * with different extensions.
766 *
767 * ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example'
768 *
769 * ca_cert = OpenSSL::X509::Certificate.new
770 * ca_cert.serial = 0
771 * ca_cert.version = 2
772 * ca_cert.not_before = Time.now
773 * ca_cert.not_after = Time.now + 86400
774 *
775 * ca_cert.public_key = ca_key.public_key
776 * ca_cert.subject = ca_name
777 * ca_cert.issuer = ca_name
778 *
779 * extension_factory = OpenSSL::X509::ExtensionFactory.new
780 * extension_factory.subject_certificate = ca_cert
781 * extension_factory.issuer_certificate = ca_cert
782 *
783 * ca_cert.add_extension \
784 * extension_factory.create_extension('subjectKeyIdentifier', 'hash')
785 *
786 * This extension indicates the CA's key may be used as a CA.
787 *
788 * ca_cert.add_extension \
789 * extension_factory.create_extension('basicConstraints', 'CA:TRUE', true)
790 *
791 * This extension indicates the CA's key may be used to verify signatures on
792 * both certificates and certificate revocations.
793 *
794 * ca_cert.add_extension \
795 * extension_factory.create_extension(
796 * 'keyUsage', 'cRLSign,keyCertSign', true)
797 *
798 * Root CA certificates are self-signed.
799 *
800 * ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new
801 *
802 * The CA certificate is saved to disk so it may be distributed to all the
803 * users of the keys this CA will sign.
804 *
805 * open 'ca_cert.pem', 'w' do |io|
806 * io.write ca_cert.to_pem
807 * end
808 *
809 * === Certificate Signing Request
810 *
811 * The CA signs keys through a Certificate Signing Request (CSR). The CSR
812 * contains the information necessary to identify the key.
813 *
814 * csr = OpenSSL::X509::Request.new
815 * csr.version = 0
816 * csr.subject = name
817 * csr.public_key = key.public_key
818 * csr.sign key, OpenSSL::Digest::SHA1.new
819 *
820 * A CSR is saved to disk and sent to the CA for signing.
821 *
822 * open 'csr.pem', 'w' do |io|
823 * io.write csr.to_pem
824 * end
825 *
826 * === Creating a Certificate from a CSR
827 *
828 * Upon receiving a CSR the CA will verify it before signing it. A minimal
829 * verification would be to check the CSR's signature.
830 *
831 * csr = OpenSSL::X509::Request.new File.read 'csr.pem'
832 *
833 * raise 'CSR can not be verified' unless csr.verify csr.public_key
834 *
835 * After verification a certificate is created, marked for various usages,
836 * signed with the CA key and returned to the requester.
837 *
838 * csr_cert = OpenSSL::X509::Certificate.new
839 * csr_cert.serial = 0
840 * csr_cert.version = 2
841 * csr_cert.not_before = Time.now
842 * csr_cert.not_after = Time.now + 600
843 *
844 * csr_cert.subject = csr.subject
845 * csr_cert.public_key = csr.public_key
846 * csr_cert.issuer = ca_cert.subject
847 *
848 * extension_factory = OpenSSL::X509::ExtensionFactory.new
849 * extension_factory.subject_certificate = csr_cert
850 * extension_factory.issuer_certificate = ca_cert
851 *
852 * csr_cert.add_extension \
853 * extension_factory.create_extension('basicConstraints', 'CA:FALSE')
854 *
855 * csr_cert.add_extension \
856 * extension_factory.create_extension(
857 * 'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature')
858 *
859 * csr_cert.add_extension \
860 * extension_factory.create_extension('subjectKeyIdentifier', 'hash')
861 *
862 * csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new
863 *
864 * open 'csr_cert.pem', 'w' do |io|
865 * io.write csr_cert.to_pem
866 * end
867 *
868 * == SSL and TLS Connections
869 *
870 * Using our created key and certificate we can create an SSL or TLS connection.
871 * An SSLContext is used to set up an SSL session.
872 *
873 * context = OpenSSL::SSL::SSLContext.new
874 *
875 * === SSL Server
876 *
877 * An SSL server requires the certificate and private key to communicate
878 * securely with its clients:
879 *
880 * context.cert = cert
881 * context.key = key
882 *
883 * Then create an SSLServer with a TCP server socket and the context. Use the
884 * SSLServer like an ordinary TCP server.
885 *
886 * require 'socket'
887 *
888 * tcp_server = TCPServer.new 5000
889 * ssl_server = OpenSSL::SSL::SSLServer.new tcp_server, context
890 *
891 * loop do
892 * ssl_connection = ssl_server.accept
893 *
894 * data = connection.gets
895 *
896 * response = "I got #{data.dump}"
897 * puts response
898 *
899 * connection.puts "I got #{data.dump}"
900 * connection.close
901 * end
902 *
903 * === SSL client
904 *
905 * An SSL client is created with a TCP socket and the context.
906 * SSLSocket#connect must be called to initiate the SSL handshake and start
907 * encryption. A key and certificate are not required for the client socket.
908 *
909 * require 'socket'
910 *
911 * tcp_client = TCPSocket.new 'localhost', 5000
912 * ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
913 * ssl_client.connect
914 *
915 * ssl_client.puts "hello server!"
916 * puts ssl_client.gets
917 *
918 * === Peer Verification
919 *
920 * An unverified SSL connection does not provide much security. For enhanced
921 * security the client or server can verify the certificate of its peer.
922 *
923 * The client can be modified to verify the server's certificate against the
924 * certificate authority's certificate:
925 *
926 * context.ca_file = 'ca_cert.pem'
927 * context.verify_mode = OpenSSL::SSL::VERIFY_PEER
928 *
929 * require 'socket'
930 *
931 * tcp_client = TCPSocket.new 'localhost', 5000
932 * ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
933 * ssl_client.connect
934 *
935 * ssl_client.puts "hello server!"
936 * puts ssl_client.gets
937 *
938 * If the server certificate is invalid or <tt>context.ca_file</tt> is not set
939 * when verifying peers an OpenSSL::SSL::SSLError will be raised.
940 *
941 */
942 void
943 Init_openssl()
944 {
945 /*
946 * Init timezone info
947 */
948 #if 0
949 tzset();
950 #endif
951
952 /*
953 * Init all digests, ciphers
954 */
955 /* CRYPTO_malloc_init(); */
956 /* ENGINE_load_builtin_engines(); */
957 OpenSSL_add_ssl_algorithms();
958 OpenSSL_add_all_algorithms();
959 ERR_load_crypto_strings();
960 SSL_load_error_strings();
961
962 /*
963 * FIXME:
964 * On unload do:
965 */
966 #if 0
967 CONF_modules_unload(1);
968 destroy_ui_method();
969 EVP_cleanup();
970 ENGINE_cleanup();
971 CRYPTO_cleanup_all_ex_data();
972 ERR_remove_state(0);
973 ERR_free_strings();
974 #endif
975
976 /*
977 * Init main module
978 */
979 mOSSL = rb_define_module("OpenSSL");
980
981 /*
982 * OpenSSL ruby extension version
983 */
984 rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));
985
986 /*
987 * Version of OpenSSL the ruby OpenSSL extension was built with
988 */
989 rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
990
991 /*
992 * Version number of OpenSSL the ruby OpenSSL extension was built with
993 * (base 16)
994 */
995 rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
996
997 /*
998 * Boolean indicating whether OpenSSL is FIPS-enabled or not
999 */
1000 #ifdef HAVE_OPENSSL_FIPS
1001 rb_define_const(mOSSL, "OPENSSL_FIPS", Qtrue);
1002 #else
1003 rb_define_const(mOSSL, "OPENSSL_FIPS", Qfalse);
1004 #endif
1005 rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1);
1006
1007 /*
1008 * Generic error,
1009 * common for all classes under OpenSSL module
1010 */
1011 eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
1012
1013 /*
1014 * Verify callback Proc index for ext-data
1015 */
1016 if ((ossl_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"ossl_verify_cb_idx", 0, 0, 0)) < 0)
1017 ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");
1018
1019 /*
1020 * Init debug core
1021 */
1022 dOSSL = Qfalse;
1023 rb_define_module_function(mOSSL, "debug", ossl_debug_get, 0);
1024 rb_define_module_function(mOSSL, "debug=", ossl_debug_set, 1);
1025 rb_define_module_function(mOSSL, "errors", ossl_get_errors, 0);
1026
1027 /*
1028 * Get ID of to_der
1029 */
1030 ossl_s_to_der = rb_intern("to_der");
1031
1032 /*
1033 * Init components
1034 */
1035 Init_ossl_bn();
1036 Init_ossl_cipher();
1037 Init_ossl_config();
1038 Init_ossl_digest();
1039 Init_ossl_hmac();
1040 Init_ossl_ns_spki();
1041 Init_ossl_pkcs12();
1042 Init_ossl_pkcs7();
1043 Init_ossl_pkcs5();
1044 Init_ossl_pkey();
1045 Init_ossl_rand();
1046 Init_ossl_ssl();
1047 Init_ossl_x509();
1048 Init_ossl_ocsp();
1049 Init_ossl_engine();
1050 Init_ossl_asn1();
1051 }
1052
1053 #if defined(OSSL_DEBUG)
1054 /*
1055 * Check if all symbols are OK with 'make LDSHARED=gcc all'
1056 */
1057 int
1058 main(int argc, char *argv[])
1059 {
1060 return 0;
1061 }
1062 #endif /* OSSL_DEBUG */
1063
tmp
volatile VALUE tmp
Definition: tcltklib.c:10209
rb_eStandardError
VALUE rb_eStandardError
Definition: error.c:509
mOSSL
VALUE mOSSL
Definition: ossl.c:259
rb_exc_new
VALUE rb_exc_new(VALUE etype, const char *ptr, long len)
Definition: error.c:536
ary
volatile VALUE ary
Definition: tcltklib.c:9713
ossl_str_new
static VALUE ossl_str_new(int size)
Definition: ossl.c:128
dOSSL
VALUE dOSSL
Definition: ossl.c:374
strlen
size_t strlen(const char *)
ossl_s_to_der
ID ossl_s_to_der
Definition: ossl.c:269
Init_ossl_config
void Init_ossl_config()
Definition: ossl_config.c:63
proc
VALUE proc
Definition: tcltklib.c:2959
i
ssize_t i
Definition: bigdecimal.c:5655
ret
int ret
Definition: tcltklib.c:280
status
int status
Definition: tcltklib.c:2197
exc
VALUE exc
Definition: tcltklib.c:3096
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
Init_ossl_bn
void Init_ossl_bn()
Definition: ossl_bn.c:736
OSSL_IMPL_SK2ARY
#define OSSL_IMPL_SK2ARY(name, type)
Definition: ossl.c:98
RSTRING_PTR
#define RSTRING_PTR(str)
NIL_P
NIL_P(eventloop_thread)
Definition: tcltklib.c:4068
rb_protect
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
Definition: eval.c:771
rb_funcall
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:545
Qtrue
return Qtrue
Definition: tcltklib.c:9610
OSSL_VERSION
#define OSSL_VERSION
Definition: ossl_version.h:14
X509_STORE_get_ex_data
void * X509_STORE_get_ex_data(X509_STORE *str, int idx)
Definition: openssl_missing.c:46
SafeStringValue
#define SafeStringValue(v)
Init_ossl_pkcs5
void Init_ossl_pkcs5()
Definition: ossl_pkcs5.c:90
Init_ossl_pkey
void Init_ossl_pkey()
Definition: ossl_pkey.c:342
ossl_make_error
static VALUE ossl_make_error(VALUE exc, const char *fmt, va_list args)
Definition: ossl.c:294
Init_ossl_pkcs12
void Init_ossl_pkcs12()
Definition: ossl_pkcs12.c:195
rb_str_new2
#define rb_str_new2
state
int state
Definition: tcltklib.c:1462
ossl_verify_cb_idx
int ossl_verify_cb_idx
Definition: ossl.c:201
ossl_get_errors
VALUE ossl_get_errors()
Definition: ossl.c:358
args
VALUE VALUE args
Definition: tcltklib.c:2561
flag
flag
Definition: tcltklib.c:2048
ossl_debug
void ossl_debug(const char *fmt,...)
Definition: ossl.c:378
fmt
const char * fmt
Definition: tcltklib.c:841
Init_ossl_pkcs7
void Init_ossl_pkcs7()
Definition: ossl_pkcs7.c:981
Init_ossl_hmac
void Init_ossl_hmac()
Definition: ossl_hmac.c:237
ossl_exc_new
VALUE ossl_exc_new(VALUE exc, const char *fmt,...)
Definition: ossl.c:339
Init_openssl
void Init_openssl()
Definition: ossl.c:943
rb_exc_raise
void rb_exc_raise(VALUE mesg)
Definition: eval.c:527
ossl_pem_passwd_cb0
static VALUE ossl_pem_passwd_cb0(VALUE flag)
Definition: ossl.c:151
ossl_fips_mode_set
static VALUE ossl_fips_mode_set(VALUE self, VALUE enabled)
Definition: ossl.c:441
ossl_x509stctx_clear_ptr
VALUE ossl_x509stctx_clear_ptr(VALUE)
Definition: ossl_x509store.c:358
ossl_to_der_if_possible
VALUE ossl_to_der_if_possible(VALUE obj)
Definition: ossl.c:283
ossl_verify_cb_args::store_ctx
VALUE store_ctx
Definition: ossl.h:173
Qfalse
return Qfalse
Definition: tcltklib.c:6779
rb_block_given_p
int rb_block_given_p(void)
Definition: eval.c:672
ossl_verify_cb_args::preverify_ok
VALUE preverify_ok
Definition: ossl.h:172
cX509Cert
VALUE cX509Cert
Definition: ossl_x509cert.c:33
Init_ossl_ssl
void Init_ossl_ssl()
Definition: ossl_ssl.c:1823
Init_ossl_ocsp
void Init_ossl_ocsp()
Definition: ossl_ocsp.c:783
Qnil
#define Qnil
Definition: tcltklib.c:1896
val
#define val
Definition: tcltklib.c:1949
ossl_x509stctx_new
VALUE ossl_x509stctx_new(X509_STORE_CTX *)
Definition: ossl_x509store.c:348
vsnprintf
vsnprintf(buf, BUFSIZ, fmt, args)
Init_ossl_asn1
void Init_ossl_asn1()
Definition: ossl_asn1.c:1444
str
static VALUE char * str
Definition: tcltklib.c:3547
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:424
ID
unsigned long ID
Definition: ripper.y:105
va_end
va_end(args)
rb_define_const
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2202
obj
static VALUE VALUE obj
Definition: tcltklib.c:3158
eOSSLError
VALUE eOSSLError
Definition: ossl.c:264
Init_ossl_rand
void Init_ossl_rand()
Definition: ossl_rand.c:182
ossl_verify_cb_args
Definition: ossl.h:170
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
err
int err
Definition: win32.c:87
Init_ossl_engine
void Init_ossl_engine()
Definition: ossl_engine.c:430
PEM_def_callback
int PEM_def_callback(char *buf, int num, int w, void *key)
Definition: openssl_missing.c:313
rb_long2int
#define rb_long2int(n)
argv
VALUE * argv
Definition: tcltklib.c:1971
ossl_debug_get
static VALUE ossl_debug_get(VALUE self)
Definition: ossl.c:397
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:934
memcpy
memcpy(buf+1, str, len)
RTEST
#define RTEST(v)
rb_define_module_function
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1512
StringValue
#define StringValue(v)
ossl_verify_cb_args::proc
VALUE proc
Definition: ossl.h:171
mode
VALUE mode
Definition: tcltklib.c:1664
argc
int argc
Definition: tcltklib.c:1970
OSSL_IMPL_ARY2SK
#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup)
Definition: ossl.c:50
rb_jump_tag
void rb_jump_tag(int tag)
Definition: eval.c:666
ossl_debug_set
static VALUE ossl_debug_set(VALUE self, VALUE val)
Definition: ossl.c:410
_
#define _(args)
Definition: dln.h:28
msg
volatile VALUE msg
Definition: tcltklib.c:3100
Init_ossl_digest
void Init_ossl_digest()
Definition: ossl_digest.c:297
size
int size
Definition: encoding.c:52
rb_set_errinfo
void rb_set_errinfo(VALUE err)
Definition: eval.c:1436
ossl_buf2str
VALUE ossl_buf2str(char *buf, int len)
Definition: ossl.c:134
INT2NUM
#define INT2NUM(x)
rb_respond_to
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1564
ossl_raise
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:328
Init_ossl_ns_spki
void Init_ossl_ns_spki()
Definition: ossl_ns_spki.c:363
RSTRING_LENINT
#define RSTRING_LENINT(str)
DupX509CertPtr
X509 * DupX509CertPtr(VALUE)
Definition: ossl_x509cert.c:102
rb_str_new
VALUE rb_str_new(const char *, long)
Definition: string.c:425
main
int main(int argc, char **argv)
Definition: nkf.c:6918
ossl.h
Init_ossl_cipher
void Init_ossl_cipher(void)
Definition: ossl_cipher.c:741
e
BDIGIT e
Definition: bigdecimal.c:5085
VALUE
unsigned long VALUE
Definition: ripper.y:104
ossl_pem_passwd_cb
int ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd)
Definition: ossl.c:162
rb_warning
void rb_warning(const char *fmt,...)
Definition: error.c:229
ossl_call_verify_cb_proc
VALUE ossl_call_verify_cb_proc(struct ossl_verify_cb_args *args)
Definition: ossl.c:204
snprintf
#define snprintf
rb_define_module
VALUE rb_define_module(const char *name)
Definition: class.c:617
rb_intern
#define rb_intern(str)
Init_ossl_x509
void Init_ossl_x509()
Definition: ossl_x509.c:20
NULL
#define NULL
Definition: _sdbm.c:103
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:216
string2hex
int string2hex(const unsigned char *buf, int buf_len, char **hexbuf, int *hexbuf_len)
Definition: ossl.c:18
ossl_verify_cb
int ossl_verify_cb(int ok, X509_STORE_CTX *ctx)
Definition: ossl.c:211
ossl_to_der
VALUE ossl_to_der(VALUE obj)
Definition: ossl.c:272
len
size_t len
Definition: tcltklib.c:3568