Ruby 1.9.3p327(2012-11-10revision37606)
ext/openssl/ossl_pkcs5.c
Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  * Copyright (C) 2007 Technorama Ltd. <oss-ruby@technorama.net>
00004  */
00005 #include "ossl.h"
00006 
00007 VALUE mPKCS5;
00008 VALUE ePKCS5;
00009 
00010 #ifdef HAVE_PKCS5_PBKDF2_HMAC
00011 /*
00012  * call-seq:
00013  *    PKCS5.pbkdf2_hmac(pass, salt, iter, keylen, digest) => string
00014  *
00015  * === Parameters
00016  * * +pass+ - string
00017  * * +salt+ - string
00018  * * +iter+ - integer - should be greater than 1000.  2000 is better.
00019  * * +keylen+ - integer
00020  * * +digest+ - a string or OpenSSL::Digest object.
00021  *
00022  * Available in OpenSSL 0.9.9?.
00023  *
00024  * Digests other than SHA1 may not be supported by other cryptography libraries.
00025  */
00026 static VALUE
00027 ossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen, VALUE digest)
00028 {
00029     VALUE str;
00030     const EVP_MD *md;
00031     int len = NUM2INT(keylen);
00032 
00033     StringValue(pass);
00034     StringValue(salt);
00035     md = GetDigestPtr(digest);
00036 
00037     str = rb_str_new(0, len);
00038 
00039     if (PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LEN(pass),
00040                           (unsigned char *)RSTRING_PTR(salt), RSTRING_LEN(salt),
00041                           NUM2INT(iter), md, len,
00042                           (unsigned char *)RSTRING_PTR(str)) != 1)
00043         ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC");
00044 
00045     return str;
00046 }
00047 #else
00048 #define ossl_pkcs5_pbkdf2_hmac rb_f_notimplement
00049 #endif
00050 
00051 
00052 #ifdef HAVE_PKCS5_PBKDF2_HMAC_SHA1
00053 /*
00054  * call-seq:
00055  *    PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) => string
00056  *
00057  * === Parameters
00058  * * +pass+ - string
00059  * * +salt+ - string
00060  * * +iter+ - integer - should be greater than 1000.  2000 is better.
00061  * * +keylen+ - integer
00062  *
00063  * This method is available almost any version OpenSSL.
00064  *
00065  * Conforms to rfc2898.
00066  */
00067 static VALUE
00068 ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE keylen)
00069 {
00070     VALUE str;
00071     int len = NUM2INT(keylen);
00072 
00073     StringValue(pass);
00074     StringValue(salt);
00075 
00076     str = rb_str_new(0, len);
00077 
00078     if (PKCS5_PBKDF2_HMAC_SHA1(RSTRING_PTR(pass), RSTRING_LENINT(pass),
00079                                (const unsigned char *)RSTRING_PTR(salt), RSTRING_LENINT(salt), NUM2INT(iter),
00080                                len, (unsigned char *)RSTRING_PTR(str)) != 1)
00081         ossl_raise(ePKCS5, "PKCS5_PBKDF2_HMAC_SHA1");
00082 
00083     return str;
00084 }
00085 #else
00086 #define ossl_pkcs5_pbkdf2_hmac_sha1 rb_f_notimplement
00087 #endif
00088 
00089 void
00090 Init_ossl_pkcs5()
00091 {
00092     /*
00093      * Password-based Encryption
00094      *
00095      */
00096     mPKCS5 = rb_define_module_under(mOSSL, "PKCS5");
00097     ePKCS5 = rb_define_class_under(mPKCS5, "PKCS5Error", eOSSLError);
00098 
00099     rb_define_module_function(mPKCS5, "pbkdf2_hmac", ossl_pkcs5_pbkdf2_hmac, 5);
00100     rb_define_module_function(mPKCS5, "pbkdf2_hmac_sha1", ossl_pkcs5_pbkdf2_hmac_sha1, 4);
00101 }
00102