diff --git a/ChangeLog b/ChangeLog index 886100fac0..3996e476b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Thu May 19 07:19:16 2011 Martin Bosslet + + * ext/openssl/ossl_pkey.c: Add documentation. + Thu May 19 07:06:56 2011 Eric Hodel * lib/benchmark.rb: Fix indentation. diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index b5047bec26..e7ec81b7ca 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -150,6 +150,13 @@ ossl_pkey_alloc(VALUE klass) return obj; } +/* + * call-seq: + * PKeyClass.new -> self + * + * Because PKey is an abstract class, actually calling this method explicitly + * will raise a +NotImplementedError+. + */ static VALUE ossl_pkey_initialize(VALUE self) { @@ -159,6 +166,23 @@ ossl_pkey_initialize(VALUE self) return self; } +/* + * call-seq: + * pkey.sign(digest, data) -> String + * + * To sign the +String+ +data+, +digest+, an instance of OpenSSL::Digest, must + * be provided. The return value is again a +String+ containing the signature. + * A PKeyError is raised should errors occur. + * Any previous state of the +Digest+ instance is irrelevant to the signature + * outcome, the digest instance is reset to its initial state during the + * operation. + * + * == Example + * data = 'Sign me!' + * digest = OpenSSL::Digest::SHA256.new + * pkey = OpenSSL::PKey::RSA.new(2048) + * signature = pkey.sign(digest, data) + */ static VALUE ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) { @@ -183,6 +207,27 @@ ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) return str; } +/* + * call-seq: + * pkey.verify(digest, signature, data) -> String + * + * To verify the +String+ +signature+, +digest+, an instance of + * OpenSSL::Digest, must be provided to re-compute the message digest of the + * original +data+, also a +String+. The return value is +true+ if the + * signature is valid, +false+ otherwise. A PKeyError is raised should errors + * occur. + * Any previous state of the +Digest+ instance is irrelevant to the validation + * outcome, the digest instance is reset to its initial state during the + * operation. + * + * == Example + * data = 'Sign me!' + * digest = OpenSSL::Digest::SHA256.new + * pkey = OpenSSL::PKey::RSA.new(2048) + * signature = pkey.sign(digest, data) + * pub_key = pkey.public_key + * puts pub_key.verify(digest, signature, data) # => true + */ static VALUE ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) { @@ -215,10 +260,74 @@ Init_ossl_pkey() mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ #endif + /* Document-module: OpenSSL::PKey + * + * == Asymmetric Public Key Algorithms + * + * Asymmetric public key algorithms solve the problem of establishing and + * sharing secret keys to en-/decrypt messages. The key in such an + * algorithm consists of two parts: a public key that may be distributed + * to others and a private key that needs to remain secret. + * + * Messages encrypted with a public key can only be encrypted by + * recipients that are in possession of the associated private key. + * Since public key algorithms are considerably slower than symmetric + * key algorithms (cf. OpenSSL::Cipher) they are often used to establish + * a symmetric key shared between two parties that are in possession of + * each other's public key. + * + * Asymmetric algorithms offer a lot of nice features that are used in a + * lot of different areas. A very common application is the creation and + * validation of digital signatures. To sign a document, the signatory + * generally uses a message digest algorithm (cf. OpenSSL::Digest) to + * compute a digest of the document that is then encrypted (i.e. signed) + * using the private key. Anyone in possession of the public key may then + * verify the signature by computing the message digest of the original + * document on their own, decrypting the signature using the signatory's + * public key and comparing the result to the message digest they + * previously computed. The signature is valid if and only if the + * decrypted signature is equal to this message digest. + * + * The PKey module offers support for three popular public/private key + * algorithms: + * * RSA (OpenSSL::PKey::RSA) + * * DSA (OpenSSL::PKey::DSA) + * * Elliptic Curve Cryptography (OpenSSL::PKey::EC) + * Each of these implementations is in fact a sub-class of the abstract + * PKey class which offers the interface for supporting digital signatures + * in the form of PKey#sign and PKey#verify. + * + * == Diffie-Hellman Key Exchange + * + * Finally PKey also features OpenSSL::PKey::DH, an implementation of + * the Diffie-Hellman key exchange protocol based on discrete logarithms + * in finite fields, the same basis that DSA is built on. + * The Diffie-Hellman protocol can be used to exchange (symmetric) keys + * over insecure channels without needing any prior joint knowledge + * between the participating parties. As the security of DH demands + * relatively long "public keys" (i.e. the part that is overtly + * transmitted between participants) DH tends to be quite slow. If + * security or speed is your primary concern, OpenSSL::PKey::EC offers + * another implementation of the Diffie-Hellman protocol. + * + */ mPKey = rb_define_module_under(mOSSL, "PKey"); + /* Document-class: OpenSSL::PKey::PKeyError + * + *Raised when errors occur during PKey#sign or PKey#verify. + */ ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError); + /* Document-class: OpenSSL::PKey::PKey + * + * An abstract class that bundles signature creation (PKey#sign) and + * validation (PKey#verify) that is common to all implementations: + * * OpenSSL::PKey::RSA + * * OpenSSL::PKey::DSA + * * OpenSSL::PKey::EC + * * OpenSSL::PKey::DH + */ cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject); rb_define_alloc_func(cPKey, ossl_pkey_alloc);