51
ossl_x509_ary2sk0(VALUE ary)
58
Check_Type(ary, T_ARRAY);
59
sk = sk_X509_new_null();
60
if (!sk) ossl_raise(eOSSLError, NULL);
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");
68
x509 = DupX509CertPtr(val); /* NEED TO DUP */
69
sk_X509_push(sk, x509);
75
ossl_protect_x509_ary2sk(VALUE ary, int *status)
77
return (STACK_OF(X509)*)rb_protect((VALUE(*)_((VALUE)))ossl_x509_ary2sk0,
82
ossl_x509_ary2sk(VALUE ary)
87
sk = ossl_protect_x509_ary2sk(ary, &status);
88
if(status) rb_jump_tag(status);
50
#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \
52
ossl_##name##_ary2sk0(VALUE ary) \
59
Check_Type(ary, T_ARRAY); \
60
sk = sk_##type##_new_null(); \
61
if (!sk) ossl_raise(eOSSLError, NULL); \
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##"); \
70
x = dup(val); /* NEED TO DUP */ \
71
sk_##type##_push(sk, x); \
77
ossl_protect_##name##_ary2sk(VALUE ary, int *status) \
79
return (STACK_OF(type)*)rb_protect( \
80
(VALUE(*)_((VALUE)))ossl_##name##_ary2sk0, \
86
ossl_##name##_ary2sk(VALUE ary) \
91
sk = ossl_protect_##name##_ary2sk(ary, &status); \
92
if (status) rb_jump_tag(status); \
96
OSSL_IMPL_ARY2SK(x509, X509, cX509Cert, DupX509CertPtr)
93
98
#define OSSL_IMPL_SK2ARY(name, type) \
419
* OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
420
* OpenSSL[http://www.openssl.org/] library.
424
* All examples assume you have loaded OpenSSL with:
428
* These examples build atop each other. For example the key created in the
429
* next is used in throughout these examples.
435
* This example creates a 2048 bit RSA keypair and writes it to the current
438
* key = OpenSSL::PKey::RSA.new 2048
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
443
* === Exporting a Key
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.
449
* cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
450
* pass_phrase = 'my secure pass phrase goes here'
452
* key_secure = key.export cipher, pass_phrase
454
* open 'private.secure.pem', 'w' do |io|
455
* io.write key_secure
458
* OpenSSL::Cipher.ciphers returns a list of available ciphers.
462
* A key can also be loaded from a file.
464
* key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
465
* key2.public? # => true
469
* key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
470
* key3.private? # => false
472
* === Loading an Encrypted Key
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
478
* key4_pem = File.read 'private.secure.pem'
479
* key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
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
489
* Documents encrypted with the public key can only be decrypted with the
492
* public_encrypted = key.public_encrypt 'top secret document'
494
* Documents encrypted with the private key can only be decrypted with the
497
* private_encrypted = key.private_encrypt 'public release document'
501
* Use the opposite key type do decrypt the document
503
* top_secret = key.public_decrypt public_encrypted
505
* public_release = key.private_decrypt private_encrypted
507
* == PKCS #5 Password-based Encryption
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.
513
* PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption
516
* pass_phrase = 'my secure pass phrase goes here'
521
* First set up the cipher for encryption
523
* encrypter = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
525
* encrypter.pkcs5_keyivgen pass_phrase, salt
527
* Then pass the data you want to encrypt through
529
* encrypted = encrypter.update 'top secret document'
530
* encrypted << encrypter.final
534
* Use a new Cipher instance set up for decryption
536
* decrypter = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
538
* decrypter.pkcs5_keyivgen pass_phrase, salt
540
* Then pass the data you want to decrypt through
542
* plain = decrypter.update encrypted
543
* plain << decrypter.final
545
* == X509 Certificates
547
* === Creating a Certificate
549
* This example creates a self-signed certificate using an RSA key and a SHA1
552
* name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
554
* cert = OpenSSL::X509::Certificate.new
557
* cert.not_before = Time.now
558
* cert.not_after = Time.now + 3600
560
* cert.public_key = key.public_key
561
* cert.subject = name
563
* === Certificate Extensions
565
* You can add extensions to the certificate with
566
* OpenSSL::SSL::ExtensionFactory to indicate the purpose of the certificate.
568
* extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert
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'
575
* === Signing a Certificate
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
583
* cert.sign key, OpenSSL::Digest::SHA1.new
585
* open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
587
* === Loading a Certificate
589
* Like a key, a cert can also be loaded from a file.
591
* cert2 = OpenSSL::X509::Certificate.new File.read 'certificate.pem'
593
* === Verifying a Certificate
595
* Certificate#verify will return true when a certificate was signed with the
598
* raise 'certificate can not be verified' unless cert2.verify key
600
* == Certificate Authority
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.
609
* CA keys are valuable, so we encrypt and save it to disk and make sure it is
610
* not readable by other users.
612
* ca_key = OpenSSL::PKey::RSA.new 2048
614
* cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
616
* open 'ca_key.pem', 'w', 0400 do |io|
617
* io.write key.export(cipher, pass_phrase)
622
* A CA certificate is created the same way we created a certificate above, but
623
* with different extensions.
625
* ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example'
627
* ca_cert = OpenSSL::X509::Certificate.new
629
* ca_cert.version = 2
630
* ca_cert.not_before = Time.now
631
* ca_cert.not_after = Time.now + 86400
633
* ca_cert.public_key = ca_key.public_key
634
* ca_cert.subject = ca_name
635
* ca_cert.issuer = ca_name
637
* extension_factory = OpenSSL::X509::ExtensionFactory.new
638
* extension_factory.subject_certificate = ca_cert
639
* extension_factory.issuer_certificate = ca_cert
641
* extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
643
* This extension indicates the CA's key may be used as a CA.
645
* extension_factory.create_extension 'basicConstraints', 'CA:TRUE', true
647
* This extension indicates the CA's key may be used to verify signatures on
648
* both certificates and certificate revocations.
650
* extension_factory.create_extension 'keyUsage', 'cRLSign,keyCertSign', true
652
* Root CA certificates are self-signed.
654
* ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new
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.
659
* open 'ca_cert.pem', 'w' do |io|
660
* io.write ca_cert.to_pem
663
* === Certificate Signing Request
665
* The CA signs keys through a Certificate Signing Request (CSR). The CSR
666
* contains the information necessary to identify the key.
668
* csr = OpenSSL::X509::Request.new
671
* csr.public_key = key.public_key
672
* csr.sign key, OpenSSL::Digest::SHA1.new
674
* A CSR is saved to disk and sent to the CA for signing.
676
* open 'csr.pem', 'w' do |io|
677
* io.write csr.to_pem
680
* === Creating a Certificate from a CSR
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.
685
* csr = OpenSSL::X509::Request.new File.read 'csr.pem'
687
* raise 'CSR can not be verified' unless csr.verify csr.public_key
689
* After verification a certificate is created, marked for various usages,
690
* signed with the CA key and returned to the requester.
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
698
* csr_cert.subject = csr.subject
699
* csr_cert.public_key = csr.public_key
700
* csr_cert.issuer = ca_cert.subject
702
* extension_factory = OpenSSL::X509::ExtensionFactory.new
703
* extension_factory.subject_certificate = csr_cert
704
* extension_factory.issuer_certificate = ca_cert
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'
711
* csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new
713
* open 'csr_cert.pem', 'w' do |io|
714
* io.write csr_cert.to_pem
717
* == SSL and TLS Connections
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.
722
* context = OpenSSL::SSL::SSLContext.new
726
* An SSL server requires the certificate and private key to communicate
727
* securely with its clients:
729
* context.cert = cert
732
* Then create an SSLServer with a TCP server socket and the context. Use the
733
* SSLServer like an ordinary TCP server.
737
* tcp_server = TCPServer.new 5000
738
* ssl_server = OpenSSL::SSL::SSLServer.new tcp_server, context
741
* ssl_connection = ssl_server.accept
743
* data = connection.gets
745
* response = "I got #{data.dump}"
748
* connection.puts "I got #{data.dump}"
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.
760
* tcp_client = TCPSocket.new 'localhost', 5000
761
* ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
764
* ssl_client.puts "hello server!"
765
* puts ssl_client.gets
767
* === Peer Verification
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.
772
* The client can be modified to verify the server's certificate against the
773
* certificate authority's certificate:
775
* context.ca_file = 'ca_cert.pem'
776
* context.verify_mode = OpenSSL::SSL::VERIFY_PEER
780
* tcp_client = TCPSocket.new 'localhost', 5000
781
* ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
784
* ssl_client.puts "hello server!"
785
* puts ssl_client.gets
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.