Class: OpenSSL::PKey::DSA (Ruby 2.2.4)
Description: Class : OpenSSL::PKey::DSA - Ruby 2.2.4

- Home
- Core 2.2.4
- Std-lib 2.2.4
- Downloads

Support for the Ruby 2.2 series has ended. See here for reference.

### Home Classes Methods

### In Files

- openssl/ossl_pkey.c

### Parent

cPKey

### Methods

- ::generate
- ::new
- #export
- #params
- #private?
- #public?
- #public_key
- #syssign
- #sysverify
- #to_der
- #to_pem
- #to_s
- #to_text

### Class/Module Index

Quicksearch

- Integer
- OpenSSL::ASN1
- OpenSSL::ASN1::ASN1Data
- OpenSSL::ASN1::ASN1Error
- OpenSSL::ASN1::Constructive
- OpenSSL::ASN1::ObjectId
- OpenSSL::ASN1::Primitive
- OpenSSL::BN
- OpenSSL::BNError
- OpenSSL::Buffering
- OpenSSL::Cipher
- OpenSSL::Cipher::Cipher
- OpenSSL::Cipher::CipherError
- OpenSSL::Config
- OpenSSL::ConfigError
- OpenSSL::Digest
- OpenSSL::Digest::DigestError
- OpenSSL::Engine
- OpenSSL::Engine::EngineError
- OpenSSL::HMAC
- OpenSSL::HMACError
- OpenSSL::Netscape
- OpenSSL::Netscape::SPKI
- OpenSSL::Netscape::SPKIError
- OpenSSL::OCSP
- OpenSSL::OCSP::BasicResponse
- OpenSSL::OCSP::CertificateId
- OpenSSL::OCSP::OCSPError
- OpenSSL::OCSP::Request
- OpenSSL::OCSP::Response
- OpenSSL::OpenSSLError
- OpenSSL::PKCS12
- OpenSSL::PKCS12::PKCS12Error
- OpenSSL::PKCS5
- OpenSSL::PKCS5::PKCS5Error
- OpenSSL::PKCS7
- OpenSSL::PKCS7::PKCS7Error
- OpenSSL::PKCS7::RecipientInfo
- OpenSSL::PKCS7::SignerInfo
- OpenSSL::PKey
- OpenSSL::PKey::DH
- OpenSSL::PKey::DHError
- OpenSSL::PKey::DSA
- OpenSSL::PKey::DSAError
- OpenSSL::PKey::EC
- OpenSSL::PKey::EC::Group
- OpenSSL::PKey::EC::Group::Error
- OpenSSL::PKey::EC::Point
- OpenSSL::PKey::EC::Point::Error
- OpenSSL::PKey::ECError
- OpenSSL::PKey::PKey
- OpenSSL::PKey::PKeyError
- OpenSSL::PKey::RSA
- OpenSSL::PKey::RSAError
- OpenSSL::Random
- OpenSSL::Random::RandomError
- OpenSSL::SSL
- OpenSSL::SSL::Nonblock
- OpenSSL::SSL::SSLContext
- OpenSSL::SSL::SSLError
- OpenSSL::SSL::SSLErrorWaitReadable
- OpenSSL::SSL::SSLErrorWaitWritable
- OpenSSL::SSL::SSLServer
- OpenSSL::SSL::SSLSocket
- OpenSSL::SSL::Session
- OpenSSL::SSL::Session::SessionError
- OpenSSL::SSL::SocketForwarder
- OpenSSL::X509
- OpenSSL::X509::Attribute
- OpenSSL::X509::AttributeError
- OpenSSL::X509::CRL
- OpenSSL::X509::CRLError
- OpenSSL::X509::Certificate
- OpenSSL::X509::CertificateError
- OpenSSL::X509::Extension
- OpenSSL::X509::ExtensionError
- OpenSSL::X509::ExtensionFactory
- OpenSSL::X509::Name
- OpenSSL::X509::Name::RFC2253DN
- OpenSSL::X509::NameError
- OpenSSL::X509::Request
- OpenSSL::X509::RequestError
- OpenSSL::X509::Revoked
- OpenSSL::X509::RevokedError
- OpenSSL::X509::Store
- OpenSSL::X509::StoreContext
- OpenSSL::X509::StoreError
- unknown

No matching classes.

# OpenSSL::PKey::DSA

DSA, the Digital Signature Algorithm, is specified in NIST's FIPS 186-3. It is an asymmetric public key algorithm that may be used similar to e.g. RSA. Please note that for OpenSSL versions prior to 1.0.0 the digest algorithms OpenSSL::Digest::DSS (equivalent to SHA) or OpenSSL::Digest::DSS1 (equivalent to SHA-1) must be used for issuing signatures with a DSA key using OpenSSL::PKey#sign. Starting with OpenSSL 1.0.0, digest algorithms are no longer restricted, any Digest may be used for signing.

### Public Class Methods

generate(size) → dsa click to toggle source

Creates a new DSA instance by generating a private/public key pair from scratch.

### Parameters¶ ↑

- `size` is an integer representing the desired key size.

                   static VALUE
    ossl_dsa_s_generate(VALUE klass, VALUE size)
    {
        DSA *dsa = dsa_generate(NUM2INT(size)); /* err handled by dsa_instance */
        VALUE obj = dsa_instance(klass, dsa);

        if (obj == Qfalse) {
            DSA_free(dsa);
            ossl_raise(eDSAError, NULL);
        }

        return obj;
    }

new([size | string [, pass]) → dsa click to toggle source

Creates a new DSA instance by reading an existing key from `string`.

### Parameters¶ ↑

- `size` is an integer representing the desired key size.

- `string` contains a DER or PEM encoded key.

- `pass` is a string that contains an optional password.

### Examples¶ ↑

    DSA.new -> dsa
    DSA.new(1024) -> dsa
    DSA.new(File.read('dsa.pem')) -> dsa
    DSA.new(File.read('dsa.pem'), 'mypassword') -> dsa

                   static VALUE
    ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
    {
        EVP_PKEY *pkey;
        DSA *dsa;
        BIO *in;
        char *passwd = NULL;
        VALUE arg, pass;

        GetPKey(self, pkey);
        if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
            dsa = DSA_new();
        }
        else if (FIXNUM_P(arg)) {
            if (!(dsa = dsa_generate(FIX2INT(arg)))) {
                ossl_raise(eDSAError, NULL);
            }
        }
        else {
            if (!NIL_P(pass)) passwd = StringValuePtr(pass);
            arg = ossl_to_der_if_possible(arg);
            in = ossl_obj2bio(arg);
            dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
            if (!dsa) {
                OSSL_BIO_reset(in);
                dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL);
            }
            if (!dsa) {
                OSSL_BIO_reset(in);
                dsa = d2i_DSAPrivateKey_bio(in, NULL);
            }
            if (!dsa) {
                OSSL_BIO_reset(in);
                dsa = d2i_DSA_PUBKEY_bio(in, NULL);
            }
            if (!dsa) {
                OSSL_BIO_reset(in);
                dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);
            }
            BIO_free(in);
            if (!dsa) {
                ERR_clear_error();
                ossl_raise(eDSAError, "Neither PUB key nor PRIV key");
            }
        }
        if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
            DSA_free(dsa);
            ossl_raise(eDSAError, NULL);
        }

        return self;
    }

### Public Instance Methods

export([cipher, password]) → aString click to toggle source
to_pem([cipher, password]) → aString
to_s([cipher, password]) → aString

Encodes this DSA to its PEM encoding.

### Parameters¶ ↑

- `cipher` is an OpenSSL::Cipher.

- `password` is a string containing your password.

### Examples¶ ↑

    DSA.to_pem -> aString
    DSA.to_pem(cipher, 'mypassword') -> aString

                   static VALUE
    ossl_dsa_export(int argc, VALUE *argv, VALUE self)
    {
        EVP_PKEY *pkey;
        BIO *out;
        const EVP_CIPHER *ciph = NULL;
        char *passwd = NULL;
        VALUE cipher, pass, str;

        GetPKeyDSA(self, pkey);
        rb_scan_args(argc, argv, "02", &cipher, &pass);
        if (!NIL_P(cipher)) {
            ciph = GetCipherPtr(cipher);
            if (!NIL_P(pass)) {
                StringValue(pass);
                if (RSTRING_LENINT(pass) < OSSL_MIN_PWD_LEN)
                    ossl_raise(eOSSLError, "OpenSSL requires passwords to be at least four characters long");
                passwd = RSTRING_PTR(pass);
            }
        }
        if (!(out = BIO_new(BIO_s_mem()))) {
            ossl_raise(eDSAError, NULL);
        }
        if (DSA_HAS_PRIVATE(pkey->pkey.dsa)) {
            if (!PEM_write_bio_DSAPrivateKey(out, pkey->pkey.dsa, ciph,
                                             NULL, 0, ossl_pem_passwd_cb, passwd)){
                BIO_free(out);
                ossl_raise(eDSAError, NULL);
            }
        } else {
            if (!PEM_write_bio_DSA_PUBKEY(out, pkey->pkey.dsa)) {
                BIO_free(out);
                ossl_raise(eDSAError, NULL);
            }
        }
        str = ossl_membio2str(out);

        return str;
    }

Also aliased as: to_pem, to_s
params → hash click to toggle source

Stores all parameters of key to the hash INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don't use :-)) (I's up to you)

                   static VALUE
    ossl_dsa_get_params(VALUE self)
    {
        EVP_PKEY *pkey;
        VALUE hash;

        GetPKeyDSA(self, pkey);

        hash = rb_hash_new();

        rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(pkey->pkey.dsa->p));
        rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(pkey->pkey.dsa->q));
        rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(pkey->pkey.dsa->g));
        rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pkey->pkey.dsa->pub_key));
        rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(pkey->pkey.dsa->priv_key));

        return hash;
    }

private? → true | false click to toggle source

Indicates whether this DSA instance has a private key associated with it or not. The private key may be retrieved with DSA#private_key.

                   static VALUE
    ossl_dsa_is_private(VALUE self)
    {
        EVP_PKEY *pkey;

        GetPKeyDSA(self, pkey);

        return (DSA_PRIVATE(self, pkey->pkey.dsa)) ? Qtrue : Qfalse;
    }

public? → true | false click to toggle source

Indicates whether this DSA instance has a public key associated with it or not. The public key may be retrieved with #public_key.

                   static VALUE
    ossl_dsa_is_public(VALUE self)
    {
        EVP_PKEY *pkey;

        GetPKeyDSA(self, pkey);

        return (pkey->pkey.dsa->pub_key) ? Qtrue : Qfalse;
    }

public_key → aDSA click to toggle source

Returns a new DSA instance that carries just the public key information. If the current instance has also private key information, this will no longer be present in the new instance. This feature is helpful for publishing the public key information without leaking any of the private information.

### Example¶ ↑

    dsa = OpenSSL::PKey::DSA.new(2048) # has public and private information
    pub_key = dsa.public_key # has only the public part available
    pub_key_der = pub_key.to_der # it's safe to publish this

                   static VALUE
    ossl_dsa_to_public_key(VALUE self)
    {
        EVP_PKEY *pkey;
        DSA *dsa;
        VALUE obj;

        GetPKeyDSA(self, pkey);
        /* err check performed by dsa_instance */
        dsa = DSAPublicKey_dup(pkey->pkey.dsa);
        obj = dsa_instance(CLASS_OF(self), dsa);
        if (obj == Qfalse) {
            DSA_free(dsa);
            ossl_raise(eDSAError, NULL);
        }
        return obj;
    }

syssign(string) → aString click to toggle source

Computes and returns the DSA signature of `string`, where `string` is expected to be an already-computed message digest of the original input data. The signature is issued using the private key of this DSA instance.

### Parameters¶ ↑

- `string` is a message digest of the original input data to be signed

### Example¶ ↑

    dsa = OpenSSL::PKey::DSA.new(2048)
    doc = "Sign me"
    digest = OpenSSL::Digest::SHA1.digest(doc)
    sig = dsa.syssign(digest)

                   static VALUE
    ossl_dsa_sign(VALUE self, VALUE data)
    {
        EVP_PKEY *pkey;
        unsigned int buf_len;
        VALUE str;

        GetPKeyDSA(self, pkey);
        StringValue(data);
        if (!DSA_PRIVATE(self, pkey->pkey.dsa)) {
            ossl_raise(eDSAError, "Private DSA key needed!");
        }
        str = rb_str_new(0, ossl_dsa_buf_size(pkey));
        if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
                      (unsigned char *)RSTRING_PTR(str),
                      &buf_len, pkey->pkey.dsa)) { /* type is ignored (0) */
            ossl_raise(eDSAError, NULL);
        }
        rb_str_set_len(str, buf_len);

        return str;
    }

sysverify(digest, sig) → true | false click to toggle source

Verifies whether the signature is valid given the message digest input. It does so by validating `sig` using the public key of this DSA instance.

### Parameters¶ ↑

- `digest` is a message digest of the original input data to be signed

- `sig` is a DSA signature value

### Example¶ ↑

    dsa = OpenSSL::PKey::DSA.new(2048)
    doc = "Sign me"
    digest = OpenSSL::Digest::SHA1.digest(doc)
    sig = dsa.syssign(digest)
    puts dsa.sysverify(digest, sig) # => true

                   static VALUE
    ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
    {
        EVP_PKEY *pkey;
        int ret;

        GetPKeyDSA(self, pkey);
        StringValue(digest);
        StringValue(sig);
        /* type is ignored (0) */
        ret = DSA_verify(0, (unsigned char *)RSTRING_PTR(digest), RSTRING_LENINT(digest),
                         (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey->pkey.dsa);
        if (ret < 0) {
            ossl_raise(eDSAError, NULL);
        }
        else if (ret == 1) {
            return Qtrue;
        }

        return Qfalse;
    }

to_der → aString click to toggle source

Encodes this DSA to its DER encoding.

                   static VALUE
    ossl_dsa_to_der(VALUE self)
    {
        EVP_PKEY *pkey;
        int (*i2d_func)_((DSA*, unsigned char**));
        unsigned char *p;
        long len;
        VALUE str;

        GetPKeyDSA(self, pkey);
        if(DSA_HAS_PRIVATE(pkey->pkey.dsa))
            i2d_func = (int(*)_((DSA*,unsigned char**)))i2d_DSAPrivateKey;
        else
            i2d_func = i2d_DSA_PUBKEY;
        if((len = i2d_func(pkey->pkey.dsa, NULL)) <= 0)
            ossl_raise(eDSAError, NULL);
        str = rb_str_new(0, len);
        p = (unsigned char *)RSTRING_PTR(str);
        if(i2d_func(pkey->pkey.dsa, &p) < 0)
            ossl_raise(eDSAError, NULL);
        ossl_str_adjust(str, p);

        return str;
    }

to_pem(p1 = v1, p2 = v2) click to toggle source
Alias for: export
to_s(p1 = v1, p2 = v2) click to toggle source
Alias for: export
to_text → aString click to toggle source

Prints all parameters of key to buffer INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don't use :-)) (I's up to you)

                   static VALUE
    ossl_dsa_to_text(VALUE self)
    {
        EVP_PKEY *pkey;
        BIO *out;
        VALUE str;

        GetPKeyDSA(self, pkey);
        if (!(out = BIO_new(BIO_s_mem()))) {
            ossl_raise(eDSAError, NULL);
        }
        if (!DSA_print(out, pkey->pkey.dsa, 0)) { /* offset = 0 */
            BIO_free(out);
            ossl_raise(eDSAError, NULL);
        }
        str = ossl_membio2str(out);

        return str;
    }