~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to ext/openssl/ossl.c

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2011-09-24 19:16:17 UTC
  • mfrom: (1.1.8 upstream) (13.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20110924191617-o1qz4rcmqjot8zuy
Tags: 1.9.3~rc1-1
* New upstream release: 1.9.3 RC1.
  + Includes load.c fixes. Closes: #639959.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * $Id: ossl.c 27440 2010-04-22 08:21:01Z nobu $
 
2
 * $Id: ossl.c 32538 2011-07-14 05:46:00Z nahi $
3
3
 * 'OpenSSL for Ruby' project
4
4
 * Copyright (C) 2001-2002  Michal Rokos <m.rokos@sh.cvut.cz>
5
5
 * All rights reserved.
47
47
/*
48
48
 * Data Conversion
49
49
 */
50
 
STACK_OF(X509) *
51
 
ossl_x509_ary2sk0(VALUE ary)
52
 
{
53
 
    STACK_OF(X509) *sk;
54
 
    VALUE val;
55
 
    X509 *x509;
56
 
    int i;
57
 
 
58
 
    Check_Type(ary, T_ARRAY);
59
 
    sk = sk_X509_new_null();
60
 
    if (!sk) ossl_raise(eOSSLError, NULL);
61
 
 
62
 
    for (i = 0; i < RARRAY_LEN(ary); i++) {
63
 
        val = rb_ary_entry(ary, i);
64
 
        if (!rb_obj_is_kind_of(val, cX509Cert)) {
65
 
            sk_X509_pop_free(sk, X509_free);
66
 
            ossl_raise(eOSSLError, "object not X509 cert in array");
67
 
        }
68
 
        x509 = DupX509CertPtr(val); /* NEED TO DUP */
69
 
        sk_X509_push(sk, x509);
70
 
    }
71
 
    return sk;
72
 
}
73
 
 
74
 
STACK_OF(X509) *
75
 
ossl_protect_x509_ary2sk(VALUE ary, int *status)
76
 
{
77
 
    return (STACK_OF(X509)*)rb_protect((VALUE(*)_((VALUE)))ossl_x509_ary2sk0,
78
 
                                       ary, status);
79
 
}
80
 
 
81
 
STACK_OF(X509) *
82
 
ossl_x509_ary2sk(VALUE ary)
83
 
{
84
 
    STACK_OF(X509) *sk;
85
 
    int status = 0;
86
 
 
87
 
    sk = ossl_protect_x509_ary2sk(ary, &status);
88
 
    if(status) rb_jump_tag(status);
89
 
 
90
 
    return sk;
91
 
}
 
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)
92
97
 
93
98
#define OSSL_IMPL_SK2ARY(name, type)            \
94
99
VALUE                                           \
117
122
}
118
123
OSSL_IMPL_SK2ARY(x509, X509)
119
124
OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
 
125
OSSL_IMPL_SK2ARY(x509name, X509_NAME)
120
126
 
121
127
static VALUE
122
128
ossl_str_new(int size)
170
176
        rflag = flag ? Qtrue : Qfalse;
171
177
        pass  = rb_protect(ossl_pem_passwd_cb0, rflag, &status);
172
178
        if (status) return -1; /* exception was raised. */
173
 
        len = RSTRING_LEN(pass);
 
179
        len = RSTRING_LENINT(pass);
174
180
        if (len < 4) { /* 4 is OpenSSL hardcoded limit */
175
181
            rb_warning("password must be longer than 4 bytes");
176
182
            continue;
217
223
            args.proc = proc;
218
224
            args.preverify_ok = ok ? Qtrue : Qfalse;
219
225
            args.store_ctx = rctx;
220
 
            ret = rb_ensure(ossl_call_verify_cb_proc, (VALUE)&args,
221
 
                            ossl_x509stctx_clear_ptr, rctx);
 
226
            ret = rb_protect((VALUE(*)(VALUE))ossl_call_verify_cb_proc, (VALUE)&args, &state);
 
227
            ossl_x509stctx_clear_ptr(rctx);
 
228
            if (state) {
 
229
                rb_warn("exception in verify_callback is ignored");
 
230
            }
222
231
        }
223
232
        if (ret == Qtrue) {
224
233
            X509_STORE_CTX_set_error(ctx, X509_V_OK);
302
311
    }
303
312
    ERR_clear_error();
304
313
 
305
 
    if(len > BUFSIZ) len = strlen(buf);
 
314
    if(len > BUFSIZ) len = rb_long2int(strlen(buf));
306
315
    return rb_exc_new(exc, buf, len);
307
316
}
308
317
 
407
416
}
408
417
 
409
418
/*
410
 
 * OSSL library init
 
419
 * OpenSSL provides SSL, TLS and general purpose cryptography.  It wraps the
 
420
 * OpenSSL[http://www.openssl.org/] library.
 
421
 *
 
422
 * = Examples
 
423
 *
 
424
 * All examples assume you have loaded OpenSSL with:
 
425
 *
 
426
 *   require 'openssl'
 
427
 *
 
428
 * These examples build atop each other.  For example the key created in the
 
429
 * next is used in throughout these examples.
 
430
 *
 
431
 * == Keys
 
432
 *
 
433
 * === Creating a Key
 
434
 *
 
435
 * This example creates a 2048 bit RSA keypair and writes it to the current
 
436
 * directory.
 
437
 *
 
438
 *   key = OpenSSL::PKey::RSA.new 2048
 
439
 *
 
440
 *   open 'private_key.pem', 'w' do |io| io.write key.to_pem end
 
441
 *   open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end
 
442
 *
 
443
 * === Exporting a Key
 
444
 *
 
445
 * Keys saved to disk without encryption are not secure as anyone who gets
 
446
 * ahold of the key may use it unless it is encrypted.  In order to securely
 
447
 * export a key you may export it with a pass phrase.
 
448
 *
 
449
 *   cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
 
450
 *   pass_phrase = 'my secure pass phrase goes here'
 
451
 *
 
452
 *   key_secure = key.export cipher, pass_phrase
 
453
 *
 
454
 *   open 'private.secure.pem', 'w' do |io|
 
455
 *     io.write key_secure
 
456
 *   end
 
457
 *
 
458
 * OpenSSL::Cipher.ciphers returns a list of available ciphers.
 
459
 *
 
460
 * === Loading a Key
 
461
 *
 
462
 * A key can also be loaded from a file.
 
463
 *
 
464
 *   key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
 
465
 *   key2.public? # => true
 
466
 *
 
467
 * or
 
468
 *
 
469
 *   key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
 
470
 *   key3.private? # => false
 
471
 *
 
472
 * === Loading an Encrypted Key
 
473
 *
 
474
 * OpenSSL will prompt you for your pass phrase when loading an encrypted key.
 
475
 * If you will not be able to type in the pass phrase you may provide it when
 
476
 * loading the key:
 
477
 *
 
478
 *   key4_pem = File.read 'private.secure.pem'
 
479
 *   key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
 
480
 *
 
481
 * == RSA Encryption
 
482
 *
 
483
 * RSA provides ecryption and decryption using the public and private keys.
 
484
 * You can use a variety of padding methods depending upon the intended use of
 
485
 * encrypted data.
 
486
 *
 
487
 * === Encryption
 
488
 *
 
489
 * Documents encrypted with the public key can only be decrypted with the
 
490
 * private key.
 
491
 *
 
492
 *   public_encrypted = key.public_encrypt 'top secret document'
 
493
 *
 
494
 * Documents encrypted with the private key can only be decrypted with the
 
495
 * public key.
 
496
 *
 
497
 *   private_encrypted = key.private_encrypt 'public release document'
 
498
 *
 
499
 * === Decryption
 
500
 *
 
501
 * Use the opposite key type do decrypt the document
 
502
 *
 
503
 *   top_secret = key.public_decrypt public_encrypted
 
504
 *
 
505
 *   public_release = key.private_decrypt private_encrypted
 
506
 *
 
507
 * == PKCS #5 Password-based Encryption
 
508
 *
 
509
 * PKCS #5 is a password-based encryption standard documented at
 
510
 * RFC2898[http://www.ietf.org/rfc/rfc2898.txt].  It allows a short password or
 
511
 * passphrase to be used to create a secure encryption key.
 
512
 *
 
513
 * PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption
 
514
 * key.
 
515
 *
 
516
 *   pass_phrase = 'my secure pass phrase goes here'
 
517
 *   salt = '8 octets'
 
518
 *
 
519
 * === Encryption
 
520
 *
 
521
 * First set up the cipher for encryption
 
522
 *
 
523
 *   encrypter = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
 
524
 *   encrypter.encrypt
 
525
 *   encrypter.pkcs5_keyivgen pass_phrase, salt
 
526
 *
 
527
 * Then pass the data you want to encrypt through
 
528
 *
 
529
 *   encrypted = encrypter.update 'top secret document'
 
530
 *   encrypted << encrypter.final
 
531
 *
 
532
 * === Decryption
 
533
 *
 
534
 * Use a new Cipher instance set up for decryption
 
535
 *
 
536
 *   decrypter = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
 
537
 *   decrypter.decrypt
 
538
 *   decrypter.pkcs5_keyivgen pass_phrase, salt
 
539
 *
 
540
 * Then pass the data you want to decrypt through
 
541
 *
 
542
 *   plain = decrypter.update encrypted
 
543
 *   plain << decrypter.final
 
544
 *
 
545
 * == X509 Certificates
 
546
 *
 
547
 * === Creating a Certificate
 
548
 *
 
549
 * This example creates a self-signed certificate using an RSA key and a SHA1
 
550
 * signature.
 
551
 *
 
552
 *   name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
 
553
 *
 
554
 *   cert = OpenSSL::X509::Certificate.new
 
555
 *   cert.version = 2
 
556
 *   cert.serial = 0
 
557
 *   cert.not_before = Time.now
 
558
 *   cert.not_after = Time.now + 3600
 
559
 *
 
560
 *   cert.public_key = key.public_key
 
561
 *   cert.subject = name
 
562
 *
 
563
 * === Certificate Extensions
 
564
 *
 
565
 * You can add extensions to the certificate with
 
566
 * OpenSSL::SSL::ExtensionFactory to indicate the purpose of the certificate.
 
567
 *
 
568
 *   extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert
 
569
 *
 
570
 *   extension_factory.create_extension 'basicConstraints', 'CA:FALSE'
 
571
 *   extension_factory.create_extension 'keyUsage',
 
572
 *     'keyEncipherment,dataEncipherment,digitalSignature'
 
573
 *   extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
 
574
 *
 
575
 * === Signing a Certificate
 
576
 *
 
577
 * To sign a certificate set the issuer and use OpenSSL::X509::Certificate#sign
 
578
 * with a digest algorithm.  This creates a self-signed cert because we're using
 
579
 * the same name and key to sign the certificate as was used to create the
 
580
 * certificate.
 
581
 *
 
582
 *   cert.issuer = name
 
583
 *   cert.sign key, OpenSSL::Digest::SHA1.new
 
584
 *
 
585
 *   open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
 
586
 *
 
587
 * === Loading a Certificate
 
588
 *
 
589
 * Like a key, a cert can also be loaded from a file.
 
590
 *
 
591
 *   cert2 = OpenSSL::X509::Certificate.new File.read 'certificate.pem'
 
592
 *
 
593
 * === Verifying a Certificate
 
594
 *
 
595
 * Certificate#verify will return true when a certificate was signed with the
 
596
 * given public key.
 
597
 *
 
598
 *   raise 'certificate can not be verified' unless cert2.verify key
 
599
 *
 
600
 * == Certificate Authority
 
601
 *
 
602
 * A certificate authority (CA) is a trusted third party that allows you to
 
603
 * verify the ownership of unknown certificates.  The CA issues key signatures
 
604
 * that indicate it trusts the user of that key.  A user encountering the key
 
605
 * can verify the signature by using the CA's public key.
 
606
 *
 
607
 * === CA Key
 
608
 *
 
609
 * CA keys are valuable, so we encrypt and save it to disk and make sure it is
 
610
 * not readable by other users.
 
611
 *
 
612
 *   ca_key = OpenSSL::PKey::RSA.new 2048
 
613
 *
 
614
 *   cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
 
615
 *
 
616
 *   open 'ca_key.pem', 'w', 0400 do |io|
 
617
 *     io.write key.export(cipher, pass_phrase)
 
618
 *   end
 
619
 *
 
620
 * === CA Certificate
 
621
 *
 
622
 * A CA certificate is created the same way we created a certificate above, but
 
623
 * with different extensions.
 
624
 *
 
625
 *   ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example'
 
626
 *
 
627
 *   ca_cert = OpenSSL::X509::Certificate.new
 
628
 *   ca_cert.serial = 0
 
629
 *   ca_cert.version = 2
 
630
 *   ca_cert.not_before = Time.now
 
631
 *   ca_cert.not_after = Time.now + 86400
 
632
 *
 
633
 *   ca_cert.public_key = ca_key.public_key
 
634
 *   ca_cert.subject = ca_name
 
635
 *   ca_cert.issuer = ca_name
 
636
 *
 
637
 *   extension_factory = OpenSSL::X509::ExtensionFactory.new
 
638
 *   extension_factory.subject_certificate = ca_cert
 
639
 *   extension_factory.issuer_certificate = ca_cert
 
640
 *
 
641
 *   extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
 
642
 *
 
643
 * This extension indicates the CA's key may be used as a CA.
 
644
 *
 
645
 *   extension_factory.create_extension 'basicConstraints', 'CA:TRUE', true
 
646
 *
 
647
 * This extension indicates the CA's key may be used to verify signatures on
 
648
 * both certificates and certificate revocations.
 
649
 *
 
650
 *   extension_factory.create_extension 'keyUsage', 'cRLSign,keyCertSign', true
 
651
 *
 
652
 * Root CA certificates are self-signed.
 
653
 *
 
654
 *   ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new
 
655
 *
 
656
 * The CA certificate is saved to disk so it may be distributed to all the
 
657
 * users of the keys this CA will sign.
 
658
 *
 
659
 *   open 'ca_cert.pem', 'w' do |io|
 
660
 *     io.write ca_cert.to_pem
 
661
 *   end
 
662
 *
 
663
 * === Certificate Signing Request
 
664
 *
 
665
 * The CA signs keys through a Certificate Signing Request (CSR).  The CSR
 
666
 * contains the information necessary to identify the key.
 
667
 *
 
668
 *   csr = OpenSSL::X509::Request.new
 
669
 *   csr.version = 0
 
670
 *   csr.subject = name
 
671
 *   csr.public_key = key.public_key
 
672
 *   csr.sign key, OpenSSL::Digest::SHA1.new
 
673
 *
 
674
 * A CSR is saved to disk and sent to the CA for signing.
 
675
 *
 
676
 *   open 'csr.pem', 'w' do |io|
 
677
 *     io.write csr.to_pem
 
678
 *   end
 
679
 *
 
680
 * === Creating a Certificate from a CSR
 
681
 *
 
682
 * Upon receiving a CSR the CA will verify it before signing it.  A minimal
 
683
 * verification would be to check the CSR's signature.
 
684
 *
 
685
 *   csr = OpenSSL::X509::Request.new File.read 'csr.pem'
 
686
 *
 
687
 *   raise 'CSR can not be verified' unless csr.verify csr.public_key
 
688
 *
 
689
 * After verification a certificate is created, marked for various usages,
 
690
 * signed with the CA key and returned to the requester.
 
691
 *
 
692
 *   csr_cert = OpenSSL::X509::Certificate.new
 
693
 *   csr_cert.serial = 0
 
694
 *   csr_cert.version = 2
 
695
 *   csr_cert.not_before = Time.now
 
696
 *   csr_cert.not_after = Time.now + 600
 
697
 *
 
698
 *   csr_cert.subject = csr.subject
 
699
 *   csr_cert.public_key = csr.public_key
 
700
 *   csr_cert.issuer = ca_cert.subject
 
701
 *
 
702
 *   extension_factory = OpenSSL::X509::ExtensionFactory.new
 
703
 *   extension_factory.subject_certificate = csr_cert
 
704
 *   extension_factory.issuer_certificate = ca_cert
 
705
 *
 
706
 *   extension_factory.create_extension 'basicConstraints', 'CA:FALSE'
 
707
 *   extension_factory.create_extension 'keyUsage',
 
708
 *     'keyEncipherment,dataEncipherment,digitalSignature'
 
709
 *   extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
 
710
 *
 
711
 *   csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new
 
712
 *
 
713
 *   open 'csr_cert.pem', 'w' do |io|
 
714
 *     io.write csr_cert.to_pem
 
715
 *   end
 
716
 *
 
717
 * == SSL and TLS Connections
 
718
 *
 
719
 * Using our created key and certificate we can create an SSL or TLS connection.
 
720
 * An SSLContext is used to set up an SSL session.
 
721
 *
 
722
 *   context = OpenSSL::SSL::SSLContext.new
 
723
 *
 
724
 * === SSL Server
 
725
 *
 
726
 * An SSL server requires the certificate and private key to communicate
 
727
 * securely with its clients:
 
728
 *
 
729
 *   context.cert = cert
 
730
 *   context.key = key
 
731
 *
 
732
 * Then create an SSLServer with a TCP server socket and the context.  Use the
 
733
 * SSLServer like an ordinary TCP server.
 
734
 *
 
735
 *   require 'socket'
 
736
 *
 
737
 *   tcp_server = TCPServer.new 5000
 
738
 *   ssl_server = OpenSSL::SSL::SSLServer.new tcp_server, context
 
739
 *
 
740
 *   loop do
 
741
 *     ssl_connection = ssl_server.accept
 
742
 *
 
743
 *     data = connection.gets
 
744
 *
 
745
 *     response = "I got #{data.dump}"
 
746
 *     puts response
 
747
 *
 
748
 *     connection.puts "I got #{data.dump}"
 
749
 *     connection.close
 
750
 *   end
 
751
 *
 
752
 * === SSL client
 
753
 *
 
754
 * An SSL client is created with a TCP socket and the context.
 
755
 * SSLSocket#connect must be called to initiate the SSL handshake and start
 
756
 * encryption.  A key and certificate are not required for the client socket.
 
757
 *
 
758
 *   require 'socket'
 
759
 *
 
760
 *   tcp_client = TCPSocket.new 'localhost', 5000
 
761
 *   ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
 
762
 *   ssl_client.connect
 
763
 *
 
764
 *   ssl_client.puts "hello server!"
 
765
 *   puts ssl_client.gets
 
766
 *
 
767
 * === Peer Verification
 
768
 *
 
769
 * An unverified SSL connection does not provide much security.  For enhanced
 
770
 * security the client or server can verify the certificate of its peer.
 
771
 *
 
772
 * The client can be modified to verify the server's certificate against the
 
773
 * certificate authority's certificate:
 
774
 *
 
775
 *   context.ca_file = 'ca_cert.pem'
 
776
 *   context.verify_mode = OpenSSL::SSL::VERIFY_PEER
 
777
 *
 
778
 *   require 'socket'
 
779
 *
 
780
 *   tcp_client = TCPSocket.new 'localhost', 5000
 
781
 *   ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
 
782
 *   ssl_client.connect
 
783
 *
 
784
 *   ssl_client.puts "hello server!"
 
785
 *   puts ssl_client.gets
 
786
 *
 
787
 * If the server certificate is invalid or <tt>context.ca_file</tt> is not set
 
788
 * when verifying peers an OpenSSL::SSL::SSLError will be raised.
 
789
 *
411
790
 */
412
791
void
413
792
Init_openssl()
449
828
    mOSSL = rb_define_module("OpenSSL");
450
829
 
451
830
    /*
452
 
     * Constants
 
831
     * OpenSSL ruby extension version
453
832
     */
454
833
    rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));
 
834
 
 
835
    /*
 
836
     * Version of OpenSSL the ruby OpenSSL extension was built with
 
837
     */
455
838
    rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
 
839
    /*
 
840
     * Version number of OpenSSL the ruby OpenSSL extension was built with
 
841
     * (base 16)
 
842
     */
456
843
    rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
457
844
 
458
845
    /*