Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

259 lines (217 sloc) 5.883 kb
/*
* $Id: ossl_ns_spki.c 25189 2009-10-02 12:04:37Z akr $
* 'OpenSSL for Ruby' project
* Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
* All rights reserved.
*/
/*
* This program is licenced under the same licence as Ruby.
* (See the file 'LICENCE'.)
*/
#include "ossl.h"
#define WrapSPKI(klass, obj, spki) do { \
if (!spki) { \
ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \
} \
obj = Data_Wrap_Struct(klass, 0, NETSCAPE_SPKI_free, spki); \
} while (0)
#define GetSPKI(obj, spki) do { \
Data_Get_Struct(obj, NETSCAPE_SPKI, spki); \
if (!spki) { \
ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \
} \
} while (0)
/*
* Classes
*/
VALUE mNetscape;
VALUE cSPKI;
VALUE eSPKIError;
/*
* Public functions
*/
/*
* Private functions
*/
static VALUE
ossl_spki_alloc(VALUE klass, SEL sel)
{
NETSCAPE_SPKI *spki;
VALUE obj;
if (!(spki = NETSCAPE_SPKI_new())) {
ossl_raise(eSPKIError, NULL);
}
WrapSPKI(klass, obj, spki);
return obj;
}
static VALUE
ossl_spki_initialize(VALUE self, SEL sel, int argc, VALUE *argv)
{
NETSCAPE_SPKI *spki;
VALUE buffer;
const unsigned char *p;
if (rb_scan_args(argc, argv, "01", &buffer) == 0) {
return self;
}
StringValue(buffer);
if (!(spki = NETSCAPE_SPKI_b64_decode(RSTRING_PTR(buffer), -1))) {
p = (unsigned char *)RSTRING_PTR(buffer);
if (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) {
ossl_raise(eSPKIError, NULL);
}
}
NETSCAPE_SPKI_free(DATA_PTR(self));
DATA_PTR(self) = spki;
ERR_clear_error();
return self;
}
static VALUE
ossl_spki_to_der(VALUE self, SEL sel)
{
NETSCAPE_SPKI *spki;
VALUE str;
long len;
unsigned char *p;
GetSPKI(self, spki);
if ((len = i2d_NETSCAPE_SPKI(spki, NULL)) <= 0)
ossl_raise(eX509CertError, NULL);
str = rb_bstr_new();
rb_bstr_resize(str, len);
p = (unsigned char *)rb_bstr_bytes(str);
if (i2d_NETSCAPE_SPKI(spki, &p) <= 0)
ossl_raise(eX509CertError, NULL);
ossl_str_adjust(str, p);
return str;
}
static VALUE
ossl_spki_to_pem(VALUE self, SEL sel)
{
NETSCAPE_SPKI *spki;
char *data;
VALUE str;
GetSPKI(self, spki);
if (!(data = NETSCAPE_SPKI_b64_encode(spki))) {
ossl_raise(eSPKIError, NULL);
}
str = ossl_buf2str(data, strlen(data));
return str;
}
static VALUE
ossl_spki_print(VALUE self, SEL sel)
{
NETSCAPE_SPKI *spki;
BIO *out;
BUF_MEM *buf;
VALUE str;
GetSPKI(self, spki);
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eSPKIError, NULL);
}
if (!NETSCAPE_SPKI_print(out, spki)) {
BIO_free(out);
ossl_raise(eSPKIError, NULL);
}
BIO_get_mem_ptr(out, &buf);
str = rb_str_new(buf->data, buf->length);
BIO_free(out);
return str;
}
static VALUE
ossl_spki_get_public_key(VALUE self, SEL sel)
{
NETSCAPE_SPKI *spki;
EVP_PKEY *pkey;
GetSPKI(self, spki);
if (!(pkey = NETSCAPE_SPKI_get_pubkey(spki))) { /* adds an reference */
ossl_raise(eSPKIError, NULL);
}
return ossl_pkey_new(pkey); /* NO DUP - OK */
}
static VALUE
ossl_spki_set_public_key(VALUE self, SEL sel, VALUE key)
{
NETSCAPE_SPKI *spki;
GetSPKI(self, spki);
if (!NETSCAPE_SPKI_set_pubkey(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */
ossl_raise(eSPKIError, NULL);
}
return key;
}
static VALUE
ossl_spki_get_challenge(VALUE self, SEL sel)
{
NETSCAPE_SPKI *spki;
GetSPKI(self, spki);
if (spki->spkac->challenge->length <= 0) {
OSSL_Debug("Challenge.length <= 0?");
return rb_str_new(0, 0);
}
return rb_str_new((const char *)spki->spkac->challenge->data,
spki->spkac->challenge->length);
}
static VALUE
ossl_spki_set_challenge(VALUE self, SEL sel, VALUE str)
{
NETSCAPE_SPKI *spki;
StringValue(str);
GetSPKI(self, spki);
if (!ASN1_STRING_set(spki->spkac->challenge, RSTRING_PTR(str),
RSTRING_LEN(str))) {
ossl_raise(eSPKIError, NULL);
}
return str;
}
static VALUE
ossl_spki_sign(VALUE self, SEL sel, VALUE key, VALUE digest)
{
NETSCAPE_SPKI *spki;
EVP_PKEY *pkey;
const EVP_MD *md;
pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
md = GetDigestPtr(digest);
GetSPKI(self, spki);
if (!NETSCAPE_SPKI_sign(spki, pkey, md)) {
ossl_raise(eSPKIError, NULL);
}
return self;
}
/*
* Checks that cert signature is made with PRIVversion of this PUBLIC 'key'
*/
static VALUE
ossl_spki_verify(VALUE self, SEL sel, VALUE key)
{
NETSCAPE_SPKI *spki;
GetSPKI(self, spki);
switch (NETSCAPE_SPKI_verify(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */
case 0:
return Qfalse;
case 1:
return Qtrue;
default:
ossl_raise(eSPKIError, NULL);
}
return Qnil; /* dummy */
}
/*
* NETSCAPE_SPKI init
*/
void
Init_ossl_ns_spki()
{
mNetscape = rb_define_module_under(mOSSL, "Netscape");
eSPKIError = rb_define_class_under(mNetscape, "SPKIError", eOSSLError);
cSPKI = rb_define_class_under(mNetscape, "SPKI", rb_cObject);
rb_objc_define_method(*(VALUE *)cSPKI, "alloc", ossl_spki_alloc, 0);
rb_objc_define_method(cSPKI, "initialize", ossl_spki_initialize, -1);
rb_objc_define_method(cSPKI, "to_der", ossl_spki_to_der, 0);
rb_objc_define_method(cSPKI, "to_pem", ossl_spki_to_pem, 0);
rb_define_alias(cSPKI, "to_s", "to_pem");
rb_objc_define_method(cSPKI, "to_text", ossl_spki_print, 0);
rb_objc_define_method(cSPKI, "public_key", ossl_spki_get_public_key, 0);
rb_objc_define_method(cSPKI, "public_key=", ossl_spki_set_public_key, 1);
rb_objc_define_method(cSPKI, "sign", ossl_spki_sign, 2);
rb_objc_define_method(cSPKI, "verify", ossl_spki_verify, 1);
rb_objc_define_method(cSPKI, "challenge", ossl_spki_get_challenge, 0);
rb_objc_define_method(cSPKI, "challenge=", ossl_spki_set_challenge, 1);
}
Jump to Line
Something went wrong with that request. Please try again.