Class: OpenSSL::PKey::DSA
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. 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.
Class Method Summary collapse
-
.generate(size) ⇒ Object
Creates a new DSA instance by generating a private/public key pair from scratch.
Instance Method Summary collapse
-
#export(*args) ⇒ Object
(also: #to_pem, #to_s)
Encodes this DSA to its PEM encoding.
-
#new([size | string [, pass])) ⇒ Object
constructor
Creates a new DSA instance by reading an existing key from
string
. -
#params ⇒ Hash
Stores all parameters of key to the hash INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don’t use :-)) (I’s up to you).
-
#private? ⇒ Boolean
Indicates whether this DSA instance has a private key associated with it or not.
-
#public? ⇒ Boolean
Indicates whether this DSA instance has a public key associated with it or not.
-
#public_key ⇒ Object
Returns a new DSA instance that carries just the public key information.
-
#syssign(string) ⇒ aString
Computes and returns the DSA signature of
string
, wherestring
is expected to be an already-computed message digest of the original input data. -
#sysverify(digest, sig) ⇒ Object
Verifies whether the signature is valid given the message digest input.
-
#to_der ⇒ aString
Encodes this DSA to its DER encoding.
-
#to_text ⇒ aString
Prints all parameters of key to buffer INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don’t use :-)) (I’s up to you).
Methods inherited from PKey
Constructor Details
#new([size | string [, pass])) ⇒ Object
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
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'ossl_pkey_dsa.c', line 206
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;
}
|
Class Method Details
.generate(size) ⇒ Object
Creates a new DSA instance by generating a private/public key pair from scratch.
Parameters
-
size
is an integer representing the desired key size.
174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'ossl_pkey_dsa.c', line 174
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 Method Details
#export([cipher, password]) ⇒ aString #to_pem([cipher, password]) ⇒ aString #to_s([cipher, password]) ⇒ aString Also known as: to_pem, to_s
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
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
# File 'ossl_pkey_dsa.c', line 310
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;
}
|
#params ⇒ Hash
Stores all parameters of key to the hash INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don’t use :-)) (I’s up to you)
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
# File 'ossl_pkey_dsa.c', line 390
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? ⇒ Boolean
Indicates whether this DSA instance has a private key associated with it or not. The private key may be retrieved with DSA#private_key.
283 284 285 286 287 288 289 290 291 |
# File 'ossl_pkey_dsa.c', line 283
static VALUE
ossl_dsa_is_private(VALUE self)
{
EVP_PKEY *pkey;
GetPKeyDSA(self, pkey);
return (DSA_PRIVATE(self, pkey->pkey.dsa)) ? Qtrue : Qfalse;
}
|
#public? ⇒ Boolean
Indicates whether this DSA instance has a public key associated with it or not. The public key may be retrieved with DSA#public_key.
266 267 268 269 270 271 272 273 274 |
# File 'ossl_pkey_dsa.c', line 266
static VALUE
ossl_dsa_is_public(VALUE self)
{
EVP_PKEY *pkey;
GetPKeyDSA(self, pkey);
return (pkey->pkey.dsa->pub_key) ? Qtrue : Qfalse;
}
|
#public_key ⇒ Object
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
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
# File 'ossl_pkey_dsa.c', line 454
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
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)
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 |
# File 'ossl_pkey_dsa.c', line 493
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) ⇒ Object
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
535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 |
# File 'ossl_pkey_dsa.c', line 535
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
Encodes this DSA to its DER encoding.
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
# File 'ossl_pkey_dsa.c', line 357
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_text ⇒ aString
Prints all parameters of key to buffer INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! Don’t use :-)) (I’s up to you)
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'ossl_pkey_dsa.c', line 417
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;
}
|