nacl 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/nacl/extconf.rb +4 -0
- data/ext/nacl/nacl.c +180 -0
- data/lib/nacl.rb +1 -0
- metadata +48 -0
data/ext/nacl/extconf.rb
ADDED
data/ext/nacl/nacl.c
ADDED
@@ -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
|
+
}
|
data/lib/nacl.rb
ADDED
@@ -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: []
|