|
1 /*-------------------------------------------------------------------------- |
|
2 * LuaSec 0.4 |
|
3 * Copyright (C) 2006-2009 Bruno Silvestre |
|
4 * |
|
5 *--------------------------------------------------------------------------*/ |
|
6 |
|
7 #include <string.h> |
|
8 |
|
9 #include <openssl/ssl.h> |
|
10 #include <openssl/x509v3.h> |
|
11 #include <openssl/err.h> |
|
12 |
|
13 #include <lua.h> |
|
14 #include <lauxlib.h> |
|
15 |
|
16 #include "io.h" |
|
17 #include "buffer.h" |
|
18 #include "timeout.h" |
|
19 #include "socket.h" |
|
20 #include "ssl.h" |
|
21 #include "x509.h" |
|
22 |
|
23 #define min(a, b) (a<b)?a:b |
|
24 |
|
25 void luasec_push_x509(lua_State* L, X509 *cert) |
|
26 { |
|
27 p_x509 cert_obj = (p_x509) lua_newuserdata(L, sizeof(t_x509)); |
|
28 cert_obj->cert = cert; |
|
29 luaL_getmetatable(L, "SSL:Certificate"); |
|
30 lua_setmetatable(L, -2); |
|
31 } |
|
32 |
|
33 X509* luasec_to_x509(lua_State* L, int idx) |
|
34 { |
|
35 return ((p_x509)luaL_checkudata(L, idx, "SSL:Certificate"))->cert; |
|
36 } |
|
37 |
|
38 int meth_decode(lua_State* L) |
|
39 { |
|
40 X509 *peer; |
|
41 X509_NAME *subject; |
|
42 int i, j, n_entries; |
|
43 |
|
44 peer = luasec_to_x509(L, 1); |
|
45 |
|
46 lua_newtable(L); /* ret */ |
|
47 |
|
48 subject = X509_get_subject_name(peer); |
|
49 |
|
50 n_entries = X509_NAME_entry_count(subject); |
|
51 |
|
52 lua_newtable(L); /* {} */ |
|
53 lua_pushvalue(L, -1); |
|
54 lua_setfield(L, -3, "subject"); /* ret.subject = {} */ |
|
55 for(i = 0; i <= n_entries; i++) |
|
56 { |
|
57 X509_NAME_ENTRY *entry; |
|
58 ASN1_OBJECT *object; |
|
59 |
|
60 entry = X509_NAME_get_entry(subject, i); |
|
61 object = X509_NAME_ENTRY_get_object(entry); |
|
62 |
|
63 luasec_push_asn1_objname(L, object, 1); |
|
64 |
|
65 if(luasec_push_subtable(L, -2)) |
|
66 { |
|
67 /* Get short/long name of the entry */ |
|
68 luasec_push_asn1_objname(L, object, 0); |
|
69 lua_setfield(L, -2, "name"); |
|
70 } |
|
71 |
|
72 luasec_push_asn1_string(L, X509_NAME_ENTRY_get_data(entry)); |
|
73 lua_rawseti(L, -2, lua_objlen(L, -2)+1); |
|
74 |
|
75 lua_pop(L, 1); |
|
76 } |
|
77 |
|
78 lua_pop(L, 1); /* ret.subject */ |
|
79 |
|
80 lua_newtable(L); /* {} */ |
|
81 lua_pushvalue(L, -1); |
|
82 lua_setfield(L, -3, "extensions"); /* ret.extensions = {} */ |
|
83 |
|
84 i = -1; |
|
85 while((i = X509_get_ext_by_NID(peer, NID_subject_alt_name, i)) != -1) |
|
86 { |
|
87 X509_EXTENSION *extension; |
|
88 STACK_OF(GENERAL_NAME) *values; |
|
89 int n_general_names; |
|
90 |
|
91 extension = X509_get_ext(peer, i); |
|
92 if(extension == NULL) |
|
93 break; |
|
94 |
|
95 values = X509V3_EXT_d2i(extension); |
|
96 if(values == NULL) |
|
97 break; |
|
98 |
|
99 /* Push ret.extensions[oid] */ |
|
100 luasec_push_asn1_objname(L, extension->object, 1); |
|
101 luasec_push_subtable(L, -2); |
|
102 /* Set ret.extensions[oid].name = name */ |
|
103 luasec_push_asn1_objname(L, extension->object, 0); |
|
104 lua_setfield(L, -2, "name"); |
|
105 |
|
106 n_general_names = sk_GENERAL_NAME_num(values); |
|
107 for(j = 0; j < n_general_names; j++) |
|
108 { |
|
109 GENERAL_NAME *general_name; |
|
110 |
|
111 general_name = sk_GENERAL_NAME_value(values, j); |
|
112 |
|
113 switch(general_name->type) |
|
114 { |
|
115 case GEN_OTHERNAME: |
|
116 { |
|
117 OTHERNAME *otherName = general_name->d.otherName; |
|
118 |
|
119 luasec_push_asn1_objname(L, otherName->type_id, 1); |
|
120 |
|
121 if(luasec_push_subtable(L, -2)) |
|
122 { |
|
123 luasec_push_asn1_objname(L, otherName->type_id, 0); |
|
124 lua_setfield(L, -2, "name"); |
|
125 } |
|
126 |
|
127 luasec_push_asn1_string(L, otherName->value->value.asn1_string); |
|
128 lua_rawseti(L, -2, lua_objlen(L, -2)+1); |
|
129 |
|
130 lua_pop(L, 1); |
|
131 break; |
|
132 } |
|
133 case GEN_DNS: |
|
134 { |
|
135 lua_pushstring(L, "dNSName"); |
|
136 luasec_push_subtable(L, -2); |
|
137 luasec_push_asn1_string(L, general_name->d.dNSName); |
|
138 lua_rawseti(L, -2, lua_objlen(L, -2)+1); |
|
139 lua_pop(L, 1); |
|
140 break; |
|
141 } |
|
142 default: |
|
143 break; |
|
144 } |
|
145 } |
|
146 |
|
147 lua_pop(L, 1); /* array */ |
|
148 i++; /* Next extension */ |
|
149 } |
|
150 lua_pop(L, 1); /* ret.extensions */ |
|
151 return 1; |
|
152 } |
|
153 |
|
154 /** |
|
155 * Certificate metamethods |
|
156 */ |
|
157 static luaL_Reg meta[] = { |
|
158 {"decode", meth_decode}, |
|
159 {NULL, NULL} |
|
160 }; |
|
161 |
|
162 LUASEC_API int luaopen_ssl_x509(lua_State *L) |
|
163 { |
|
164 /* Register the functions and tables */ |
|
165 luaL_newmetatable(L, "SSL:Certificate"); |
|
166 lua_newtable(L); |
|
167 luaL_register(L, NULL, meta); |
|
168 lua_setfield(L, -2, "__index"); |
|
169 } |