Ruby 1.9.3p327(2012-11-10revision37606)
|
00001 /* 00002 * $Id: ossl_ns_spki.c 31166 2011-03-24 07:29:21Z naruse $ 00003 * 'OpenSSL for Ruby' project 00004 * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> 00005 * All rights reserved. 00006 */ 00007 /* 00008 * This program is licenced under the same licence as Ruby. 00009 * (See the file 'LICENCE'.) 00010 */ 00011 #include "ossl.h" 00012 00013 #define WrapSPKI(klass, obj, spki) do { \ 00014 if (!(spki)) { \ 00015 ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ 00016 } \ 00017 (obj) = Data_Wrap_Struct((klass), 0, NETSCAPE_SPKI_free, (spki)); \ 00018 } while (0) 00019 #define GetSPKI(obj, spki) do { \ 00020 Data_Get_Struct((obj), NETSCAPE_SPKI, (spki)); \ 00021 if (!(spki)) { \ 00022 ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ 00023 } \ 00024 } while (0) 00025 00026 /* 00027 * Classes 00028 */ 00029 VALUE mNetscape; 00030 VALUE cSPKI; 00031 VALUE eSPKIError; 00032 00033 /* 00034 * Public functions 00035 */ 00036 00037 /* 00038 * Private functions 00039 */ 00040 static VALUE 00041 ossl_spki_alloc(VALUE klass) 00042 { 00043 NETSCAPE_SPKI *spki; 00044 VALUE obj; 00045 00046 if (!(spki = NETSCAPE_SPKI_new())) { 00047 ossl_raise(eSPKIError, NULL); 00048 } 00049 WrapSPKI(klass, obj, spki); 00050 00051 return obj; 00052 } 00053 00054 static VALUE 00055 ossl_spki_initialize(int argc, VALUE *argv, VALUE self) 00056 { 00057 NETSCAPE_SPKI *spki; 00058 VALUE buffer; 00059 const unsigned char *p; 00060 00061 if (rb_scan_args(argc, argv, "01", &buffer) == 0) { 00062 return self; 00063 } 00064 StringValue(buffer); 00065 if (!(spki = NETSCAPE_SPKI_b64_decode(RSTRING_PTR(buffer), -1))) { 00066 p = (unsigned char *)RSTRING_PTR(buffer); 00067 if (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) { 00068 ossl_raise(eSPKIError, NULL); 00069 } 00070 } 00071 NETSCAPE_SPKI_free(DATA_PTR(self)); 00072 DATA_PTR(self) = spki; 00073 ERR_clear_error(); 00074 00075 return self; 00076 } 00077 00078 static VALUE 00079 ossl_spki_to_der(VALUE self) 00080 { 00081 NETSCAPE_SPKI *spki; 00082 VALUE str; 00083 long len; 00084 unsigned char *p; 00085 00086 GetSPKI(self, spki); 00087 if ((len = i2d_NETSCAPE_SPKI(spki, NULL)) <= 0) 00088 ossl_raise(eX509CertError, NULL); 00089 str = rb_str_new(0, len); 00090 p = (unsigned char *)RSTRING_PTR(str); 00091 if (i2d_NETSCAPE_SPKI(spki, &p) <= 0) 00092 ossl_raise(eX509CertError, NULL); 00093 ossl_str_adjust(str, p); 00094 00095 return str; 00096 } 00097 00098 static VALUE 00099 ossl_spki_to_pem(VALUE self) 00100 { 00101 NETSCAPE_SPKI *spki; 00102 char *data; 00103 VALUE str; 00104 00105 GetSPKI(self, spki); 00106 if (!(data = NETSCAPE_SPKI_b64_encode(spki))) { 00107 ossl_raise(eSPKIError, NULL); 00108 } 00109 str = ossl_buf2str(data, rb_long2int(strlen(data))); 00110 00111 return str; 00112 } 00113 00114 static VALUE 00115 ossl_spki_print(VALUE self) 00116 { 00117 NETSCAPE_SPKI *spki; 00118 BIO *out; 00119 BUF_MEM *buf; 00120 VALUE str; 00121 00122 GetSPKI(self, spki); 00123 if (!(out = BIO_new(BIO_s_mem()))) { 00124 ossl_raise(eSPKIError, NULL); 00125 } 00126 if (!NETSCAPE_SPKI_print(out, spki)) { 00127 BIO_free(out); 00128 ossl_raise(eSPKIError, NULL); 00129 } 00130 BIO_get_mem_ptr(out, &buf); 00131 str = rb_str_new(buf->data, buf->length); 00132 BIO_free(out); 00133 00134 return str; 00135 } 00136 00137 static VALUE 00138 ossl_spki_get_public_key(VALUE self) 00139 { 00140 NETSCAPE_SPKI *spki; 00141 EVP_PKEY *pkey; 00142 00143 GetSPKI(self, spki); 00144 if (!(pkey = NETSCAPE_SPKI_get_pubkey(spki))) { /* adds an reference */ 00145 ossl_raise(eSPKIError, NULL); 00146 } 00147 00148 return ossl_pkey_new(pkey); /* NO DUP - OK */ 00149 } 00150 00151 static VALUE 00152 ossl_spki_set_public_key(VALUE self, VALUE key) 00153 { 00154 NETSCAPE_SPKI *spki; 00155 00156 GetSPKI(self, spki); 00157 if (!NETSCAPE_SPKI_set_pubkey(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */ 00158 ossl_raise(eSPKIError, NULL); 00159 } 00160 00161 return key; 00162 } 00163 00164 static VALUE 00165 ossl_spki_get_challenge(VALUE self) 00166 { 00167 NETSCAPE_SPKI *spki; 00168 00169 GetSPKI(self, spki); 00170 if (spki->spkac->challenge->length <= 0) { 00171 OSSL_Debug("Challenge.length <= 0?"); 00172 return rb_str_new(0, 0); 00173 } 00174 00175 return rb_str_new((const char *)spki->spkac->challenge->data, 00176 spki->spkac->challenge->length); 00177 } 00178 00179 static VALUE 00180 ossl_spki_set_challenge(VALUE self, VALUE str) 00181 { 00182 NETSCAPE_SPKI *spki; 00183 00184 StringValue(str); 00185 GetSPKI(self, spki); 00186 if (!ASN1_STRING_set(spki->spkac->challenge, RSTRING_PTR(str), 00187 RSTRING_LENINT(str))) { 00188 ossl_raise(eSPKIError, NULL); 00189 } 00190 00191 return str; 00192 } 00193 00194 static VALUE 00195 ossl_spki_sign(VALUE self, VALUE key, VALUE digest) 00196 { 00197 NETSCAPE_SPKI *spki; 00198 EVP_PKEY *pkey; 00199 const EVP_MD *md; 00200 00201 pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ 00202 md = GetDigestPtr(digest); 00203 GetSPKI(self, spki); 00204 if (!NETSCAPE_SPKI_sign(spki, pkey, md)) { 00205 ossl_raise(eSPKIError, NULL); 00206 } 00207 00208 return self; 00209 } 00210 00211 /* 00212 * Checks that cert signature is made with PRIVversion of this PUBLIC 'key' 00213 */ 00214 static VALUE 00215 ossl_spki_verify(VALUE self, VALUE key) 00216 { 00217 NETSCAPE_SPKI *spki; 00218 00219 GetSPKI(self, spki); 00220 switch (NETSCAPE_SPKI_verify(spki, GetPKeyPtr(key))) { /* NO NEED TO DUP */ 00221 case 0: 00222 return Qfalse; 00223 case 1: 00224 return Qtrue; 00225 default: 00226 ossl_raise(eSPKIError, NULL); 00227 } 00228 return Qnil; /* dummy */ 00229 } 00230 00231 /* 00232 * NETSCAPE_SPKI init 00233 */ 00234 void 00235 Init_ossl_ns_spki() 00236 { 00237 mNetscape = rb_define_module_under(mOSSL, "Netscape"); 00238 00239 eSPKIError = rb_define_class_under(mNetscape, "SPKIError", eOSSLError); 00240 00241 cSPKI = rb_define_class_under(mNetscape, "SPKI", rb_cObject); 00242 00243 rb_define_alloc_func(cSPKI, ossl_spki_alloc); 00244 rb_define_method(cSPKI, "initialize", ossl_spki_initialize, -1); 00245 00246 rb_define_method(cSPKI, "to_der", ossl_spki_to_der, 0); 00247 rb_define_method(cSPKI, "to_pem", ossl_spki_to_pem, 0); 00248 rb_define_alias(cSPKI, "to_s", "to_pem"); 00249 rb_define_method(cSPKI, "to_text", ossl_spki_print, 0); 00250 rb_define_method(cSPKI, "public_key", ossl_spki_get_public_key, 0); 00251 rb_define_method(cSPKI, "public_key=", ossl_spki_set_public_key, 1); 00252 rb_define_method(cSPKI, "sign", ossl_spki_sign, 2); 00253 rb_define_method(cSPKI, "verify", ossl_spki_verify, 1); 00254 rb_define_method(cSPKI, "challenge", ossl_spki_get_challenge, 0); 00255 rb_define_method(cSPKI, "challenge=", ossl_spki_set_challenge, 1); 00256 } 00257 00258