nacl 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/ext/nacl/extconf.rb +4 -0
  2. data/ext/nacl/nacl.c +180 -0
  3. data/lib/nacl.rb +1 -0
  4. metadata +48 -0
@@ -0,0 +1,4 @@
1
+ require 'mkmf'
2
+
3
+ have_library "nacl"
4
+ create_makefile('nacl/nacl')
@@ -0,0 +1,180 @@
1
+ #include <ruby.h>
2
+ #include <crypto_box.h>
3
+ #include <crypto_sign.h>
4
+ #include <crypto_hash.h>
5
+ #include <crypto_hash_sha256.h>
6
+ #include <crypto_hash_sha512.h>
7
+
8
+ VALUE NaCl = Qnil, OpenError = Qnil;
9
+
10
+ #define CHECK_STRING_LENGTH(str, len) do { Check_Type(str, T_STRING); if (RSTRING_LEN(str) != len) rb_raise(rb_eArgError, #str " must be %d bytes long", len); } while (0)
11
+
12
+ unsigned long long allocate_and_prepend_zeros(VALUE source, unsigned long long padding_len, char **padded, char **result) {
13
+ unsigned long long mlen = RSTRING_LEN(source) + padding_len;
14
+
15
+ *padded = (char *)malloc(mlen);
16
+ if (*padded == NULL) rb_raise(rb_eNoMemError, "out of memory");
17
+
18
+ *result = (char *)malloc(mlen);
19
+ if (*result == NULL)
20
+ {
21
+ free(*padded);
22
+ rb_raise(rb_eNoMemError, "out of memory");
23
+ }
24
+
25
+ memset(*padded, 0, padding_len);
26
+ memcpy(*padded + padding_len, RSTRING_PTR(source), RSTRING_LEN(source));
27
+ return mlen;
28
+ }
29
+
30
+ /**********************************************************************************/
31
+
32
+ VALUE method_crypto_box_keypair(VALUE self) {
33
+ unsigned char pk[crypto_box_PUBLICKEYBYTES];
34
+ unsigned char sk[crypto_box_SECRETKEYBYTES];
35
+ VALUE keys[2];
36
+
37
+ crypto_box_keypair(pk, sk);
38
+ keys[0] = rb_str_new(pk, crypto_box_PUBLICKEYBYTES);
39
+ keys[1] = rb_str_new(sk, crypto_box_SECRETKEYBYTES);
40
+ return rb_ary_new4(2, keys);
41
+ }
42
+
43
+ VALUE method_crypto_box(VALUE self, VALUE message, VALUE nonce, VALUE pk, VALUE sk) {
44
+ char *padded_message, *result;
45
+ VALUE return_value;
46
+ unsigned long long mlen;
47
+ int n;
48
+
49
+ Check_Type(message, T_STRING);
50
+ Check_Type(nonce, T_STRING);
51
+ CHECK_STRING_LENGTH(nonce, crypto_box_NONCEBYTES);
52
+ CHECK_STRING_LENGTH(pk, crypto_box_PUBLICKEYBYTES);
53
+ CHECK_STRING_LENGTH(sk, crypto_box_SECRETKEYBYTES);
54
+
55
+ mlen = allocate_and_prepend_zeros(message, crypto_box_ZEROBYTES, &padded_message, &result);
56
+ n = crypto_box(result, padded_message, mlen, RSTRING_PTR(nonce), RSTRING_PTR(pk), RSTRING_PTR(sk));
57
+
58
+ if (n == 0) return_value = rb_str_new(result + crypto_box_BOXZEROBYTES, mlen - crypto_box_BOXZEROBYTES);
59
+ memset(padded_message, 0, mlen);
60
+ free(result);
61
+ free(padded_message);
62
+ if (n != 0) rb_raise(rb_eRuntimeError, "crypto_box failed");
63
+ return return_value;
64
+ }
65
+
66
+ VALUE method_crypto_box_open(VALUE self, VALUE ciphertext, VALUE nonce, VALUE pk, VALUE sk) {
67
+ char *p, *padded_ciphertext, *result;
68
+ VALUE return_value;
69
+ unsigned long long mlen;
70
+ int n;
71
+
72
+ Check_Type(ciphertext, T_STRING);
73
+ if (RSTRING_LEN(ciphertext) < crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES) rb_raise(rb_eArgError, "ciphertext must be at least %d bytes long", crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES);
74
+ CHECK_STRING_LENGTH(nonce, crypto_box_NONCEBYTES);
75
+ CHECK_STRING_LENGTH(pk, crypto_box_PUBLICKEYBYTES);
76
+ CHECK_STRING_LENGTH(sk, crypto_box_SECRETKEYBYTES);
77
+
78
+ mlen = allocate_and_prepend_zeros(ciphertext, crypto_box_BOXZEROBYTES, &padded_ciphertext, &result);
79
+ n = crypto_box_open(result, padded_ciphertext, mlen, RSTRING_PTR(nonce), RSTRING_PTR(pk), RSTRING_PTR(sk));
80
+
81
+ if (n == 0) return_value = rb_str_new(result + crypto_box_ZEROBYTES, mlen - crypto_box_ZEROBYTES);
82
+ memset(result, 0, mlen);
83
+ free(padded_ciphertext);
84
+ free(result);
85
+ if (n != 0) rb_raise(OpenError, "crypto_box_open failed");
86
+ return return_value;
87
+ }
88
+
89
+ /**********************************************************************************/
90
+
91
+ VALUE method_crypto_sign_keypair(VALUE self) {
92
+ unsigned char pk[crypto_sign_PUBLICKEYBYTES];
93
+ unsigned char sk[crypto_sign_SECRETKEYBYTES];
94
+ VALUE keys[2];
95
+
96
+ crypto_sign_keypair(pk, sk);
97
+ keys[0] = rb_str_new(pk, crypto_sign_PUBLICKEYBYTES);
98
+ keys[1] = rb_str_new(sk, crypto_sign_SECRETKEYBYTES);
99
+ return rb_ary_new4(2, keys);
100
+ }
101
+
102
+ VALUE method_crypto_sign(VALUE self, VALUE message, VALUE sk) {
103
+ char *result;
104
+ VALUE return_value;
105
+ unsigned long long smlen;
106
+
107
+ Check_Type(message, T_STRING);
108
+ CHECK_STRING_LENGTH(sk, crypto_sign_SECRETKEYBYTES);
109
+
110
+ result = (char *)malloc(RSTRING_LEN(message) + crypto_sign_BYTES);
111
+ if (result == NULL) rb_raise(rb_eNoMemError, "out of memory");
112
+
113
+ crypto_sign(result, &smlen, RSTRING_PTR(message), RSTRING_LEN(message), RSTRING_PTR(sk));
114
+
115
+ return_value = rb_str_new(result, smlen);
116
+ free(result);
117
+ return return_value;
118
+ }
119
+
120
+ VALUE method_crypto_sign_open(VALUE self, VALUE signed_message, VALUE pk) {
121
+ char *result;
122
+ VALUE return_value;
123
+ unsigned long long mlen;
124
+ int n;
125
+
126
+ Check_Type(signed_message, T_STRING);
127
+ if (RSTRING_LEN(signed_message) == 0) rb_raise(OpenError, "crypto_sign_open failed");
128
+ CHECK_STRING_LENGTH(pk, crypto_sign_PUBLICKEYBYTES);
129
+
130
+ result = (char *)malloc(RSTRING_LEN(signed_message));
131
+ if (result == NULL) rb_raise(rb_eNoMemError, "out of memory");
132
+
133
+ n = crypto_sign_open(result, &mlen, RSTRING_PTR(signed_message), RSTRING_LEN(signed_message), RSTRING_PTR(pk));
134
+
135
+ if (n == 0) return_value = rb_str_new(result, mlen);
136
+ free(result);
137
+ if (n != 0) rb_raise(OpenError, "crypto_sign_open failed");
138
+ return return_value;
139
+ }
140
+
141
+ /**********************************************************************************/
142
+
143
+ VALUE method_crypto_hash(VALUE self, VALUE data) {
144
+ unsigned char h[crypto_hash_BYTES];
145
+ Check_Type(data, T_STRING);
146
+ crypto_hash(h, RSTRING_PTR(data), RSTRING_LEN(data));
147
+ return rb_str_new(h, crypto_hash_BYTES);
148
+ }
149
+
150
+ VALUE method_crypto_hash_sha256(VALUE self, VALUE data) {
151
+ unsigned char h[crypto_hash_sha256_BYTES];
152
+ Check_Type(data, T_STRING);
153
+ crypto_hash_sha256(h, RSTRING_PTR(data), RSTRING_LEN(data));
154
+ return rb_str_new(h, crypto_hash_sha256_BYTES);
155
+ }
156
+
157
+ VALUE method_crypto_hash_sha512(VALUE self, VALUE data) {
158
+ unsigned char h[crypto_hash_sha512_BYTES];
159
+ Check_Type(data, T_STRING);
160
+ crypto_hash_sha512(h, RSTRING_PTR(data), RSTRING_LEN(data));
161
+ return rb_str_new(h, crypto_hash_sha512_BYTES);
162
+ }
163
+
164
+ void Init_nacl() {
165
+ NaCl = rb_define_module("NaCl");
166
+
167
+ rb_define_module_function(NaCl, "crypto_box_keypair", method_crypto_box_keypair, 0);
168
+ rb_define_module_function(NaCl, "crypto_box", method_crypto_box, 4);
169
+ rb_define_module_function(NaCl, "crypto_box_open", method_crypto_box_open, 4);
170
+
171
+ rb_define_module_function(NaCl, "crypto_sign_keypair", method_crypto_sign_keypair, 0);
172
+ rb_define_module_function(NaCl, "crypto_sign", method_crypto_sign, 2);
173
+ rb_define_module_function(NaCl, "crypto_sign_open", method_crypto_sign_open, 2);
174
+
175
+ rb_define_module_function(NaCl, "crypto_hash", method_crypto_hash, 1);
176
+ rb_define_module_function(NaCl, "crypto_hash_sha256", method_crypto_hash_sha256, 1);
177
+ rb_define_module_function(NaCl, "crypto_hash_sha512", method_crypto_hash_sha512, 1);
178
+
179
+ OpenError = rb_define_class_under(NaCl, "OpenError", rb_eStandardError);
180
+ }
@@ -0,0 +1 @@
1
+ require 'nacl/nacl'
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nacl
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Roger Nesbitt
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-09 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description:
15
+ email: roger@seriousorange.com
16
+ executables: []
17
+ extensions:
18
+ - ext/nacl/extconf.rb
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/nacl.rb
22
+ - ext/nacl/nacl.c
23
+ - ext/nacl/extconf.rb
24
+ homepage: http://github.com/mogest/nacl
25
+ licenses: []
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 1.8.23
45
+ signing_key:
46
+ specification_version: 3
47
+ summary: Ruby wrapper around djb's NaCl networking and cryptography library
48
+ test_files: []