• Main Page
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

ext/openssl/ossl_x509attr.c

Go to the documentation of this file.
00001 /*
00002  * $Id: ossl_x509attr.c 27437 2010-04-22 08:04:13Z nobu $
00003  * 'OpenSSL for Ruby' project
00004  * Copyright (C) 2001 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 WrapX509Attr(klass, obj, attr) do { \
00014     if (!attr) { \
00015         ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \
00016     } \
00017     obj = Data_Wrap_Struct(klass, 0, X509_ATTRIBUTE_free, attr); \
00018 } while (0)
00019 #define GetX509Attr(obj, attr) do { \
00020     Data_Get_Struct(obj, X509_ATTRIBUTE, attr); \
00021     if (!attr) { \
00022         ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \
00023     } \
00024 } while (0)
00025 #define SafeGetX509Attr(obj, attr) do { \
00026     OSSL_Check_Kind(obj, cX509Attr); \
00027     GetX509Attr(obj, attr); \
00028 } while (0)
00029 
00030 /*
00031  * Classes
00032  */
00033 VALUE cX509Attr;
00034 VALUE eX509AttrError;
00035 
00036 /*
00037  * Public
00038  */
00039 VALUE
00040 ossl_x509attr_new(X509_ATTRIBUTE *attr)
00041 {
00042     X509_ATTRIBUTE *new;
00043     VALUE obj;
00044 
00045     if (!attr) {
00046         new = X509_ATTRIBUTE_new();
00047     } else {
00048         new = X509_ATTRIBUTE_dup(attr);
00049     }
00050     if (!new) {
00051         ossl_raise(eX509AttrError, NULL);
00052     }
00053     WrapX509Attr(cX509Attr, obj, new);
00054 
00055     return obj;
00056 }
00057 
00058 X509_ATTRIBUTE *
00059 DupX509AttrPtr(VALUE obj)
00060 {
00061     X509_ATTRIBUTE *attr, *new;
00062 
00063     SafeGetX509Attr(obj, attr);
00064     if (!(new = X509_ATTRIBUTE_dup(attr))) {
00065         ossl_raise(eX509AttrError, NULL);
00066     }
00067 
00068     return new;
00069 }
00070 
00071 /*
00072  * Private
00073  */
00074 static VALUE
00075 ossl_x509attr_alloc(VALUE klass)
00076 {
00077     X509_ATTRIBUTE *attr;
00078     VALUE obj;
00079 
00080     if (!(attr = X509_ATTRIBUTE_new()))
00081         ossl_raise(eX509AttrError, NULL);
00082     WrapX509Attr(klass, obj, attr);
00083 
00084     return obj;
00085 }
00086 
00087 /*
00088  * call-seq:
00089  *    Attribute.new(oid [, value]) => attr
00090  */
00091 static VALUE
00092 ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self)
00093 {
00094     VALUE oid, value;
00095     X509_ATTRIBUTE *attr, *x;
00096     const unsigned char *p;
00097 
00098     GetX509Attr(self, attr);
00099     if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){
00100         oid = ossl_to_der_if_possible(oid);
00101         StringValue(oid);
00102         p = (unsigned char *)RSTRING_PTR(oid);
00103         x = d2i_X509_ATTRIBUTE(&attr, &p, RSTRING_LEN(oid));
00104         DATA_PTR(self) = attr;
00105         if(!x){
00106             ossl_raise(eX509AttrError, NULL);
00107         }
00108         return self;
00109     }
00110     rb_funcall(self, rb_intern("oid="), 1, oid);
00111     rb_funcall(self, rb_intern("value="), 1, value);
00112 
00113     return self;
00114 }
00115 
00116 /*
00117  * call-seq:
00118  *    attr.oid = string => string
00119  */
00120 static VALUE
00121 ossl_x509attr_set_oid(VALUE self, VALUE oid)
00122 {
00123     X509_ATTRIBUTE *attr;
00124     ASN1_OBJECT *obj;
00125     char *s;
00126 
00127     s = StringValuePtr(oid);
00128     obj = OBJ_txt2obj(s, 0);
00129     if(!obj) obj = OBJ_txt2obj(s, 1);
00130     if(!obj) ossl_raise(eX509AttrError, NULL);
00131     GetX509Attr(self, attr);
00132     X509_ATTRIBUTE_set1_object(attr, obj);
00133 
00134     return oid;
00135 }
00136 
00137 /*
00138  * call-seq:
00139  *    attr.oid => string
00140  */
00141 static VALUE
00142 ossl_x509attr_get_oid(VALUE self)
00143 {
00144     X509_ATTRIBUTE *attr;
00145     ASN1_OBJECT *oid;
00146     BIO *out;
00147     VALUE ret;
00148     int nid;
00149 
00150     GetX509Attr(self, attr);
00151     oid = X509_ATTRIBUTE_get0_object(attr);
00152     if ((nid = OBJ_obj2nid(oid)) != NID_undef)
00153         ret = rb_str_new2(OBJ_nid2sn(nid));
00154     else{
00155         if (!(out = BIO_new(BIO_s_mem())))
00156             ossl_raise(eX509AttrError, NULL);
00157         i2a_ASN1_OBJECT(out, oid);
00158         ret = ossl_membio2str(out);
00159     }
00160 
00161     return ret;
00162 }
00163 
00164 #if defined(HAVE_ST_X509_ATTRIBUTE_SINGLE) || defined(HAVE_ST_SINGLE)
00165 #  define OSSL_X509ATTR_IS_SINGLE(attr)  ((attr)->single)
00166 #  define OSSL_X509ATTR_SET_SINGLE(attr) ((attr)->single = 1)
00167 #else
00168 #  define OSSL_X509ATTR_IS_SINGLE(attr)  (!(attr)->set)
00169 #  define OSSL_X509ATTR_SET_SINGLE(attr) ((attr)->set = 0)
00170 #endif
00171 
00172 /*
00173  * call-seq:
00174  *    attr.value = asn1 => asn1
00175  */
00176 static VALUE
00177 ossl_x509attr_set_value(VALUE self, VALUE value)
00178 {
00179     X509_ATTRIBUTE *attr;
00180     ASN1_TYPE *a1type;
00181 
00182     if(!(a1type = ossl_asn1_get_asn1type(value)))
00183         ossl_raise(eASN1Error, "could not get ASN1_TYPE");
00184     if(ASN1_TYPE_get(a1type) == V_ASN1_SEQUENCE){
00185         ASN1_TYPE_free(a1type);
00186         ossl_raise(eASN1Error, "couldn't set SEQUENCE for attribute value.");
00187     }
00188     GetX509Attr(self, attr);
00189     if(attr->value.set){
00190         if(OSSL_X509ATTR_IS_SINGLE(attr)) ASN1_TYPE_free(attr->value.single);
00191         else sk_ASN1_TYPE_free(attr->value.set);
00192     }
00193     OSSL_X509ATTR_SET_SINGLE(attr);
00194     attr->value.single = a1type;
00195 
00196     return value;
00197 }
00198 
00199 /*
00200  * call-seq:
00201  *    attr.value => asn1
00202  */
00203 static VALUE
00204 ossl_x509attr_get_value(VALUE self)
00205 {
00206     X509_ATTRIBUTE *attr;
00207     VALUE str, asn1;
00208     long length;
00209     unsigned char *p;
00210 
00211     GetX509Attr(self, attr);
00212     if(attr->value.ptr == NULL) return Qnil;
00213     if(OSSL_X509ATTR_IS_SINGLE(attr)){
00214         length = i2d_ASN1_TYPE(attr->value.single, NULL);
00215         str = rb_str_new(0, length);
00216         p = (unsigned char *)RSTRING_PTR(str);
00217         i2d_ASN1_TYPE(attr->value.single, &p);
00218         ossl_str_adjust(str, p);
00219     }
00220     else{
00221         length = i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set,
00222                         (unsigned char **) NULL, i2d_ASN1_TYPE,
00223                         V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
00224         str = rb_str_new(0, length);
00225         p = (unsigned char *)RSTRING_PTR(str);
00226         i2d_ASN1_SET_OF_ASN1_TYPE(attr->value.set, &p,
00227                         i2d_ASN1_TYPE, V_ASN1_SET, V_ASN1_UNIVERSAL, 0);
00228         ossl_str_adjust(str, p);
00229     }
00230     asn1 = rb_funcall(mASN1, rb_intern("decode"), 1, str);
00231 
00232     return asn1;
00233 }
00234 
00235 /*
00236  * call-seq:
00237  *    attr.to_der => string
00238  */
00239 static VALUE
00240 ossl_x509attr_to_der(VALUE self)
00241 {
00242     X509_ATTRIBUTE *attr;
00243     VALUE str;
00244     int len;
00245     unsigned char *p;
00246 
00247     GetX509Attr(self, attr);
00248     if((len = i2d_X509_ATTRIBUTE(attr, NULL)) <= 0)
00249         ossl_raise(eX509AttrError, NULL);
00250     str = rb_str_new(0, len);
00251     p = (unsigned char *)RSTRING_PTR(str);
00252     if(i2d_X509_ATTRIBUTE(attr, &p) <= 0)
00253         ossl_raise(eX509AttrError, NULL);
00254     rb_str_set_len(str, p - (unsigned char*)RSTRING_PTR(str));
00255 
00256     return str;
00257 }
00258 
00259 /*
00260  * X509_ATTRIBUTE init
00261  */
00262 void
00263 Init_ossl_x509attr()
00264 {
00265     eX509AttrError = rb_define_class_under(mX509, "AttributeError", eOSSLError);
00266 
00267     cX509Attr = rb_define_class_under(mX509, "Attribute", rb_cObject);
00268     rb_define_alloc_func(cX509Attr, ossl_x509attr_alloc);
00269     rb_define_method(cX509Attr, "initialize", ossl_x509attr_initialize, -1);
00270     rb_define_method(cX509Attr, "oid=", ossl_x509attr_set_oid, 1);
00271     rb_define_method(cX509Attr, "oid", ossl_x509attr_get_oid, 0);
00272     rb_define_method(cX509Attr, "value=", ossl_x509attr_set_value, 1);
00273     rb_define_method(cX509Attr, "value", ossl_x509attr_get_value, 0);
00274     rb_define_method(cX509Attr, "to_der", ossl_x509attr_to_der, 0);
00275 }
00276 

Generated on Sat Jul 7 2012 15:29:11 for Ruby by  doxygen 1.7.1