Class: OpenSSL::PKey::DSA
| Relationships & Source Files | |
| Super Chains via Extension / Inclusion / Inheritance | |
| 
         Class Chain: 
        
          self,
           
      PKey
         | 
    |
| 
         Instance Chain: 
        
          self,
           
      PKey
         | 
    |
| Inherits: | 
        OpenSSL::PKey::PKey
        
  | 
    
| Defined in: | ext/openssl/ossl_pkey_dsa.c | 
Overview
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.
Class Method Summary
- 
    
      .generate(size)  ⇒ DSA 
    
    
Creates a new
DSAinstance by generating a private/public key pair from scratch. - 
    
      .new  ⇒ DSA 
    
    constructor
    
Creates a new
DSAinstance by reading an existing key from string. 
PKey - Inherited
| .new | Because PKey is an abstract class, actually calling this method explicitly will raise a NotImplementedError.  | 
    
Instance Attribute Summary
- 
    
      #private?  ⇒ Boolean 
    
    readonly
    
Indicates whether this
DSAinstance has a private key associated with it or not. - 
    
      #public?  ⇒ Boolean 
    
    readonly
    
Indicates whether this
DSAinstance has a public key associated with it or not. 
Instance Method Summary
- 
    
      #export([cipher, password])  ⇒ String 
    
    
Alias for #to_s.
 - #initialize_copy(other)
 - 
    
      #params  ⇒ Hash 
    
    
Stores all parameters of key to the hash INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don’t use :-)) (I’s up to you).
 - 
    
      #public_key  ⇒ DSA 
    
    
Returns a new
DSAinstance that carries just the public key information. - 
    
      #set_key(pub_key, priv_key)  ⇒ self 
    
    
Sets pub_key and priv_key for the
DSAinstance. - 
    
      #set_pqg(p, q, g)  ⇒ self 
    
    
Sets p, q, g to the
DSAinstance. - 
    
      #syssign(string)  ⇒ String 
    
    
Computes and returns the
DSAsignature of string, where string is expected to be an already-computed message digest of the original input data. - 
    
      #sysverify(digest, sig)  ⇒ Boolean 
    
    
Verifies whether the signature is valid given the message digest input.
 - 
    
      #to_der  ⇒ String 
    
    
Encodes this
DSAto its DER encoding. - 
    
      #to_pem([cipher, password])  ⇒ String 
    
    
Alias for #to_s.
 - 
    
      #to_s([cipher, password])  ⇒ String 
      (also: #export, #to_pem)
    
    
Encodes this
DSAto its PEM encoding. - 
    
      #to_text  ⇒ String 
    
    
Prints all parameters of key to buffer INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don’t use :-)) (I’s up to you).
 
PKey - Inherited
| #sign | To sign the String data, digest, an instance of   | 
    
| #verify | To verify the String signature, digest, an instance of   | 
    
Constructor Details
    
      .new  ⇒ DSA 
      .new(size)  ⇒ DSA 
      .new(string [, pass])  ⇒ DSA 
    
  
DSA 
      .new(size)  ⇒ DSA 
      .new(string [, pass])  ⇒ DSA 
    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
  # File 'ext/openssl/ossl_pkey_dsa.c', line 212
static VALUE
ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
{
    EVP_PKEY *pkey;
    DSA *dsa;
    BIO *in;
    VALUE arg, pass;
    GetPKey(self, pkey);
    if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) {
        dsa = DSA_new();
    }
    else if (RB_INTEGER_TYPE_P(arg)) {
	if (!(dsa = dsa_generate(NUM2INT(arg)))) {
	    ossl_raise(eDSAError, NULL);
	}
    }
    else {
	pass = ossl_pem_passwd_value(pass);
	arg = ossl_to_der_if_possible(arg);
	in = ossl_obj2bio(&arg);
	dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass);
	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);
#define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
	(d2i_of_void *)d2i_DSAPublicKey, PEM_STRING_DSA_PUBLIC, (bp), (void **)(x), (cb), (u))
	    dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);
#undef PEM_read_bio_DSAPublicKey
	}
	BIO_free(in);
	if (!dsa) {
	    ossl_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;
}
  Class Method Details
    .generate(size)  ⇒ DSA   
Creates a new DSA instance by generating a private/public key pair from scratch.
Parameters
- 
size is an integer representing the desired key size.
 
# File 'ext/openssl/ossl_pkey_dsa.c', line 178
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;
}
  Instance Attribute Details
    #private?  ⇒ Boolean  (readonly)  
Indicates whether this DSA instance has a private key associated with it or not. The private key may be retrieved with DSA#private_key.
# File 'ext/openssl/ossl_pkey_dsa.c', line 313
static VALUE
ossl_dsa_is_private(VALUE self)
{
    DSA *dsa;
    GetDSA(self, dsa);
    return DSA_PRIVATE(self, dsa) ? Qtrue : Qfalse;
}
  
    #public?  ⇒ Boolean  (readonly)  
Indicates whether this DSA instance has a public key associated with it or not. The public key may be retrieved with #public_key.
# File 'ext/openssl/ossl_pkey_dsa.c', line 294
static VALUE
ossl_dsa_is_public(VALUE self)
{
    DSA *dsa;
    const BIGNUM *bn;
    GetDSA(self, dsa);
    DSA_get0_key(dsa, &bn, NULL);
    return bn ? Qtrue : Qfalse;
}
  Instance Method Details
    
      #export([cipher, password])  ⇒ String 
      #to_pem([cipher, password])  ⇒ String 
      #to_s([cipher, password])  ⇒ String 
    
  
String 
      #to_pem([cipher, password])  ⇒ String 
      #to_s([cipher, password])  ⇒ String 
    Alias for #to_s.
#initialize_copy(other)
[ GitHub ]# File 'ext/openssl/ossl_pkey_dsa.c', line 267
static VALUE
ossl_dsa_initialize_copy(VALUE self, VALUE other)
{
    EVP_PKEY *pkey;
    DSA *dsa, *dsa_new;
    GetPKey(self, pkey);
    if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE)
	ossl_raise(eDSAError, "DSA already initialized");
    GetDSA(other, dsa);
    dsa_new = ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, (d2i_of_void *)d2i_DSAPrivateKey, (char *)dsa);
    if (!dsa_new)
	ossl_raise(eDSAError, "ASN1_dup");
    EVP_PKEY_assign_DSA(pkey, dsa_new);
    return self;
}
  
    #params  ⇒ Hash   
Stores all parameters of key to the hash INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don’t use :-)) (I’s up to you)
# File 'ext/openssl/ossl_pkey_dsa.c', line 415
static VALUE
ossl_dsa_get_params(VALUE self)
{
    DSA *dsa;
    VALUE hash;
    const BIGNUM *p, *q, *g, *pub_key, *priv_key;
    GetDSA(self, dsa);
    DSA_get0_pqg(dsa, &p, &q, &g);
    DSA_get0_key(dsa, &pub_key, &priv_key);
    hash = rb_hash_new();
    rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p));
    rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q));
    rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g));
    rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key));
    rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key));
    return hash;
}
  
    #public_key  ⇒ DSA   
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
  # File 'ext/openssl/ossl_pkey_dsa.c', line 481
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 */
#define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup( \
	(i2d_of_void *)i2d_DSAPublicKey, (d2i_of_void *)d2i_DSAPublicKey, (char *)(dsa))
    dsa = DSAPublicKey_dup(EVP_PKEY_get0_DSA(pkey));
#undef DSAPublicKey_dup
    obj = dsa_instance(rb_obj_class(self), dsa);
    if (obj == Qfalse) {
	DSA_free(dsa);
	ossl_raise(eDSAError, NULL);
    }
    return obj;
}
  
    #set_key(pub_key, priv_key)  ⇒ self   
Sets pub_key and priv_key for the DSA instance. priv_key may be nil.
    #set_pqg(p, q, g)  ⇒ self   
Sets p, q, g to the DSA instance.
    #syssign(string)  ⇒ String   
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)
  # File 'ext/openssl/ossl_pkey_dsa.c', line 521
static VALUE
ossl_dsa_sign(VALUE self, VALUE data)
{
    DSA *dsa;
    const BIGNUM *dsa_q;
    unsigned int buf_len;
    VALUE str;
    GetDSA(self, dsa);
    DSA_get0_pqg(dsa, NULL, &dsa_q, NULL);
    if (!dsa_q)
	ossl_raise(eDSAError, "incomplete DSA");
    if (!DSA_PRIVATE(self, dsa))
	ossl_raise(eDSAError, "Private DSA key needed!");
    StringValue(data);
    str = rb_str_new(0, DSA_size(dsa));
    if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data),
		  (unsigned char *)RSTRING_PTR(str),
		  &buf_len, dsa)) { /* type is ignored (0) */
	ossl_raise(eDSAError, NULL);
    }
    rb_str_set_len(str, buf_len);
    return str;
}
  
    #sysverify(digest, sig)  ⇒ Boolean   
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
DSAsignature 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
  # File 'ext/openssl/ossl_pkey_dsa.c', line 566
static VALUE
ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig)
{
    DSA *dsa;
    int ret;
    GetDSA(self, dsa);
    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), dsa);
    if (ret < 0) {
	ossl_raise(eDSAError, NULL);
    }
    else if (ret == 1) {
	return Qtrue;
    }
    return Qfalse;
}
  
    #to_der  ⇒ String   
Encodes this DSA to its DER encoding.
# File 'ext/openssl/ossl_pkey_dsa.c', line 381
static VALUE
ossl_dsa_to_der(VALUE self)
{
    DSA *dsa;
    int (*i2d_func)(DSA *, unsigned char **);
    unsigned char *p;
    long len;
    VALUE str;
    GetDSA(self, dsa);
    if(DSA_HAS_PRIVATE(dsa))
	i2d_func = (int (*)(DSA *,unsigned char **))i2d_DSAPrivateKey;
    else
	i2d_func = i2d_DSA_PUBKEY;
    if((len = i2d_func(dsa, NULL)) <= 0)
	ossl_raise(eDSAError, NULL);
    str = rb_str_new(0, len);
    p = (unsigned char *)RSTRING_PTR(str);
    if(i2d_func(dsa, &p) < 0)
	ossl_raise(eDSAError, NULL);
    ossl_str_adjust(str, p);
    return str;
}
  
    
      #export([cipher, password])  ⇒ String 
      #to_pem([cipher, password])  ⇒ String 
      #to_s([cipher, password])  ⇒ String 
    
  
String 
      #to_pem([cipher, password])  ⇒ String 
      #to_s([cipher, password])  ⇒ String 
    Alias for #to_s.
    
      #export([cipher, password])  ⇒ String 
      #to_pem([cipher, password])  ⇒ String 
      #to_s([cipher, password])  ⇒ String 
    
    Also known as: #export, #to_pem
  
String 
      #to_pem([cipher, password])  ⇒ String 
      #to_s([cipher, password])  ⇒ String 
    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
  # File 'ext/openssl/ossl_pkey_dsa.c', line 340
static VALUE
ossl_dsa_export(int argc, VALUE *argv, VALUE self)
{
    DSA *dsa;
    BIO *out;
    const EVP_CIPHER *ciph = NULL;
    VALUE cipher, pass, str;
    GetDSA(self, dsa);
    rb_scan_args(argc, argv, "02", &cipher, &pass);
    if (!NIL_P(cipher)) {
	ciph = ossl_evp_get_cipherbyname(cipher);
	pass = ossl_pem_passwd_value(pass);
    }
    if (!(out = BIO_new(BIO_s_mem()))) {
	ossl_raise(eDSAError, NULL);
    }
    if (DSA_HAS_PRIVATE(dsa)) {
	if (!PEM_write_bio_DSAPrivateKey(out, dsa, ciph, NULL, 0,
					 ossl_pem_passwd_cb, (void *)pass)){
	    BIO_free(out);
	    ossl_raise(eDSAError, NULL);
	}
    } else {
	if (!PEM_write_bio_DSA_PUBKEY(out, dsa)) {
	    BIO_free(out);
	    ossl_raise(eDSAError, NULL);
	}
    }
    str = ossl_membio2str(out);
    return str;
}
  
    #to_text  ⇒ String   
Prints all parameters of key to buffer INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don’t use :-)) (I’s up to you)
# File 'ext/openssl/ossl_pkey_dsa.c', line 444
static VALUE
ossl_dsa_to_text(VALUE self)
{
    DSA *dsa;
    BIO *out;
    VALUE str;
    GetDSA(self, dsa);
    if (!(out = BIO_new(BIO_s_mem()))) {
	ossl_raise(eDSAError, NULL);
    }
    if (!DSA_print(out, dsa, 0)) { /* offset = 0 */
	BIO_free(out);
	ossl_raise(eDSAError, NULL);
    }
    str = ossl_membio2str(out);
    return str;
}