qr_reader-native 0.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.
- checksums.yaml +7 -0
- data/LICENSE-mruby.txt +22 -0
- data/LICENSE-spinel.txt +19 -0
- data/LICENSE.txt +21 -0
- data/README.md +61 -0
- data/ext/qr_reader_native/SPINEL_VERSION +1 -0
- data/ext/qr_reader_native/extconf.rb +8 -0
- data/ext/qr_reader_native/mruby/error.h +13 -0
- data/ext/qr_reader_native/mruby/internal.h +145 -0
- data/ext/qr_reader_native/mruby/string.h +22 -0
- data/ext/qr_reader_native/mruby.h +93 -0
- data/ext/qr_reader_native/mruby_shim.h +118 -0
- data/ext/qr_reader_native/qr_reader_native.c +13513 -0
- data/ext/qr_reader_native/qr_reader_native.h +29 -0
- data/ext/qr_reader_native/qr_reader_native_ext.c +598 -0
- data/ext/qr_reader_native/re_cased.h +71 -0
- data/ext/qr_reader_native/re_compile.c +5784 -0
- data/ext/qr_reader_native/re_ctype.h +3540 -0
- data/ext/qr_reader_native/re_exec.c +2190 -0
- data/ext/qr_reader_native/re_internal.h +671 -0
- data/ext/qr_reader_native/re_prop.h +4629 -0
- data/ext/qr_reader_native/re_spinel.c +363 -0
- data/ext/qr_reader_native/re_spinel.h +22 -0
- data/ext/qr_reader_native/re_spinel_utf8.inc +97 -0
- data/ext/qr_reader_native/re_utf8.c +156 -0
- data/ext/qr_reader_native/sp_alloc.c +1447 -0
- data/ext/qr_reader_native/sp_alloc.h +1196 -0
- data/ext/qr_reader_native/sp_argf.h +33 -0
- data/ext/qr_reader_native/sp_array.c +1052 -0
- data/ext/qr_reader_native/sp_array.h +456 -0
- data/ext/qr_reader_native/sp_bigint.c +5826 -0
- data/ext/qr_reader_native/sp_bigint.h +117 -0
- data/ext/qr_reader_native/sp_cold.c +5259 -0
- data/ext/qr_reader_native/sp_compat.h +402 -0
- data/ext/qr_reader_native/sp_core.c +818 -0
- data/ext/qr_reader_native/sp_core.h +56 -0
- data/ext/qr_reader_native/sp_crypto.c +877 -0
- data/ext/qr_reader_native/sp_crypto.h +169 -0
- data/ext/qr_reader_native/sp_dtoa.c +1533 -0
- data/ext/qr_reader_native/sp_dtoa.h +29 -0
- data/ext/qr_reader_native/sp_encoding_names.h +172 -0
- data/ext/qr_reader_native/sp_enum.h +86 -0
- data/ext/qr_reader_native/sp_exc.c +1185 -0
- data/ext/qr_reader_native/sp_exc.h +186 -0
- data/ext/qr_reader_native/sp_exc_ctx.h +56 -0
- data/ext/qr_reader_native/sp_fiber.c +889 -0
- data/ext/qr_reader_native/sp_fiber.h +162 -0
- data/ext/qr_reader_native/sp_fiber_ctx.h +84 -0
- data/ext/qr_reader_native/sp_format.c +695 -0
- data/ext/qr_reader_native/sp_format.h +83 -0
- data/ext/qr_reader_native/sp_gc.c +1793 -0
- data/ext/qr_reader_native/sp_gc.h +762 -0
- data/ext/qr_reader_native/sp_hash.c +131 -0
- data/ext/qr_reader_native/sp_hash.h +131 -0
- data/ext/qr_reader_native/sp_inspect.c +215 -0
- data/ext/qr_reader_native/sp_inspect.h +128 -0
- data/ext/qr_reader_native/sp_io.c +1676 -0
- data/ext/qr_reader_native/sp_io.h +272 -0
- data/ext/qr_reader_native/sp_iobuffer.c +1014 -0
- data/ext/qr_reader_native/sp_iobuffer.h +167 -0
- data/ext/qr_reader_native/sp_marshal.c +487 -0
- data/ext/qr_reader_native/sp_marshal.h +60 -0
- data/ext/qr_reader_native/sp_net.c +1029 -0
- data/ext/qr_reader_native/sp_net.h +205 -0
- data/ext/qr_reader_native/sp_pack.c +1254 -0
- data/ext/qr_reader_native/sp_poly_cold.c +1220 -0
- data/ext/qr_reader_native/sp_proc.c +410 -0
- data/ext/qr_reader_native/sp_proc.h +327 -0
- data/ext/qr_reader_native/sp_process.c +547 -0
- data/ext/qr_reader_native/sp_process_status.c +211 -0
- data/ext/qr_reader_native/sp_process_status.h +66 -0
- data/ext/qr_reader_native/sp_random.c +287 -0
- data/ext/qr_reader_native/sp_random.h +52 -0
- data/ext/qr_reader_native/sp_range.h +144 -0
- data/ext/qr_reader_native/sp_re.c +1379 -0
- data/ext/qr_reader_native/sp_re.h +186 -0
- data/ext/qr_reader_native/sp_re_names.h +59 -0
- data/ext/qr_reader_native/sp_sched.c +4044 -0
- data/ext/qr_reader_native/sp_sched.h +295 -0
- data/ext/qr_reader_native/sp_slab.c +1507 -0
- data/ext/qr_reader_native/sp_str.c +1462 -0
- data/ext/qr_reader_native/sp_str.h +306 -0
- data/ext/qr_reader_native/sp_str_crypt.c +23 -0
- data/ext/qr_reader_native/sp_string.c +92 -0
- data/ext/qr_reader_native/sp_string.h +253 -0
- data/ext/qr_reader_native/sp_system.c +78 -0
- data/ext/qr_reader_native/sp_system.h +18 -0
- data/ext/qr_reader_native/sp_time.c +860 -0
- data/ext/qr_reader_native/sp_time.h +100 -0
- data/ext/qr_reader_native/sp_types.h +292 -0
- data/ext/qr_reader_native/spinel_rt.h +19017 -0
- data/ext/qr_reader_native/unicase.c +399 -0
- data/ext/qr_reader_native/unicase.h +901 -0
- data/lib/qr_reader/native.rb +6 -0
- metadata +153 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/* sp_crypto.h -- Compact SHA-256 / HMAC / PBKDF2 / Base64URL / CSPRNG
|
|
2
|
+
*
|
|
3
|
+
* Pure C, no spinel-runtime dependency. Intended for spinel programs
|
|
4
|
+
* that need a small in-tree crypto surface without dragging in
|
|
5
|
+
* OpenSSL or libsodium. Sibling to sp_bigint.{h,c} in scope: a
|
|
6
|
+
* vendored, audit-sized C helper that ships with spinel so apps
|
|
7
|
+
* don't each reinvent it.
|
|
8
|
+
*
|
|
9
|
+
* The seven functions below are the canonical surface tep ended up
|
|
10
|
+
* with after a year of building on the same primitives -- if you
|
|
11
|
+
* find yourself wanting a different shape, please file an issue
|
|
12
|
+
* before adding to this list. The point is to keep the surface
|
|
13
|
+
* small enough to read in one sitting.
|
|
14
|
+
*
|
|
15
|
+
* Naming
|
|
16
|
+
* ------
|
|
17
|
+
* All exported symbols use the `sp_crypto_` prefix (matches the
|
|
18
|
+
* `sp_bigint_` convention). State buffers are per-function statics
|
|
19
|
+
* -- the next call to the same function clobbers the buffer, so
|
|
20
|
+
* copy on the caller side if the value must outlive the next call.
|
|
21
|
+
*
|
|
22
|
+
* Inputs
|
|
23
|
+
* ------
|
|
24
|
+
* String inputs are NUL-terminated. Length is taken via strlen()
|
|
25
|
+
* inside each function. For binary-safe inputs (containing embedded
|
|
26
|
+
* NULs), use the explicit-length internal API exposed by including
|
|
27
|
+
* this header in your own .c file -- see sp_crypto.c for the
|
|
28
|
+
* declarations.
|
|
29
|
+
*
|
|
30
|
+
* Thread safety
|
|
31
|
+
* -------------
|
|
32
|
+
* The return buffers are SP_TLS, so an answer belongs to the thread
|
|
33
|
+
* that asked for it. The clobber rule above still holds, per thread:
|
|
34
|
+
* the next call to the same function on the SAME thread overwrites
|
|
35
|
+
* it, and a caller that needs the value to outlive that call still
|
|
36
|
+
* copies.
|
|
37
|
+
*
|
|
38
|
+
* They were process-global until #4174, whose SecureRandom draw made
|
|
39
|
+
* the cost visible -- eight threads minting tokens got about a third
|
|
40
|
+
* of them from another thread's buffer. Every function here has the
|
|
41
|
+
* same window, because every call site copies out of the buffer after
|
|
42
|
+
* the call has RETURNED. "Caller-side serialize" was not a contract
|
|
43
|
+
* a caller could keep: Digest::SHA256.hexdigest is an ordinary Ruby
|
|
44
|
+
* method with nothing at the call site to serialize against.
|
|
45
|
+
*
|
|
46
|
+
* SP_TLS is __thread only in the -DSP_THREADS runtime variant, so a
|
|
47
|
+
* program that never threads pays nothing: its sp_crypto.o is the
|
|
48
|
+
* byte-identical object it was. The threaded variant pays the buffers
|
|
49
|
+
* per WORKER -- ~32 KiB of that is the two 16 KiB base64url buffers
|
|
50
|
+
* and everything else together is under 600 bytes -- and the worker
|
|
51
|
+
* pool is bounded by min(cores, SPINEL_WORKERS), not by the number of
|
|
52
|
+
* Ruby threads the program starts.
|
|
53
|
+
*/
|
|
54
|
+
#ifndef SP_CRYPTO_H
|
|
55
|
+
#define SP_CRYPTO_H
|
|
56
|
+
|
|
57
|
+
#ifdef __cplusplus
|
|
58
|
+
extern "C" {
|
|
59
|
+
#endif
|
|
60
|
+
|
|
61
|
+
/* SHA-1(msg) -> 40-char lowercase hex. Legacy hash, kept for
|
|
62
|
+
* WebSocket handshake (RFC 6455 §1.3 requires SHA-1). Do NOT
|
|
63
|
+
* use for new security designs; SHA-256 is the right primitive. */
|
|
64
|
+
const char *sp_crypto_sha1_hex(const char *msg);
|
|
65
|
+
|
|
66
|
+
/* SHA-256(msg) -> 64-char lowercase hex. */
|
|
67
|
+
const char *sp_crypto_sha256_hex(const char *msg);
|
|
68
|
+
|
|
69
|
+
/* Raw digest bytes: 32 for SHA-256, 20 for SHA-1. The result is NOT
|
|
70
|
+
* NUL-terminated data -- it is arbitrary bytes -- so the length is published
|
|
71
|
+
* in sp_ffi_bin_len (sp_alloc.h) for the `:cbinstr` / `:binstr` return modes
|
|
72
|
+
* to pick up. Callers reading these directly must use the same length. */
|
|
73
|
+
const char *sp_crypto_sha256_bin(const char *msg);
|
|
74
|
+
const char *sp_crypto_sha1_bin(const char *msg);
|
|
75
|
+
|
|
76
|
+
/* MD5(msg) -> 32-char lowercase hex / the raw 16 digest bytes. Legacy hash,
|
|
77
|
+
* bound for Digest::MD5 (Active Storage's direct-upload checksum). Do NOT
|
|
78
|
+
* use for new security designs. */
|
|
79
|
+
const char *sp_crypto_md5_hex(const char *msg);
|
|
80
|
+
const char *sp_crypto_md5_bin(const char *msg);
|
|
81
|
+
|
|
82
|
+
/* Digest::X.base64digest: strict base64 of the raw digest (24, 28 and 44
|
|
83
|
+
* chars, `=` padded). */
|
|
84
|
+
const char *sp_crypto_md5_b64(const char *msg);
|
|
85
|
+
const char *sp_crypto_sha1_b64(const char *msg);
|
|
86
|
+
const char *sp_crypto_sha256_b64(const char *msg);
|
|
87
|
+
|
|
88
|
+
/* Sec-WebSocket-Accept = base64(SHA-1(client_key + GUID)) per
|
|
89
|
+
* RFC 6455 §1.3. Returns a 28-char string ending in `=`. The
|
|
90
|
+
* only modern use case for SHA-1 in this codebase; sugars the
|
|
91
|
+
* concat+sha1+base64 dance into one call. */
|
|
92
|
+
const char *sp_crypto_websocket_accept(const char *client_key);
|
|
93
|
+
|
|
94
|
+
/* HMAC-SHA256(key, msg) -> 64-char lowercase hex. */
|
|
95
|
+
const char *sp_crypto_hmac_sha256_hex(const char *key, const char *msg);
|
|
96
|
+
|
|
97
|
+
/* HMAC-SHA256(key, msg) -> 43-char unpadded base64url. */
|
|
98
|
+
const char *sp_crypto_hmac_sha256_b64url(const char *key, const char *msg);
|
|
99
|
+
|
|
100
|
+
/* HMAC-SHA256(key, msg) / HMAC-SHA1(key, msg) -> the raw digest bytes
|
|
101
|
+
* (32 and 20). Same buffer contract as sp_crypto_sha256_bin above: the
|
|
102
|
+
* result is not NUL-terminated, and its length rides sp_ffi_bin_len.
|
|
103
|
+
*
|
|
104
|
+
* The hex spellings beside these are the right primitive when a human or
|
|
105
|
+
* a protocol header reads the answer. These are for when it feeds another
|
|
106
|
+
* primitive: HKDF (RFC 5869) is HMAC over raw bytes twice, and hex-then-
|
|
107
|
+
* decode would be a lossless detour with a chance to get the decode
|
|
108
|
+
* wrong. */
|
|
109
|
+
const char *sp_crypto_hmac_sha256_bin(const char *key, const char *msg);
|
|
110
|
+
const char *sp_crypto_hmac_sha1_bin(const char *key, const char *msg);
|
|
111
|
+
|
|
112
|
+
/* HMAC-SHA1(key, msg) -> 40-char lowercase hex. Here for the same
|
|
113
|
+
* reason sp_crypto_websocket_accept is -- an existing protocol names
|
|
114
|
+
* SHA-1 and reproducing it is not a new security design. Rails signs
|
|
115
|
+
* cookies with HMAC-SHA1 unless the app sets
|
|
116
|
+
* config.action_dispatch.cookies_digest, so a program reading one has
|
|
117
|
+
* no choice of digest. Do NOT reach for this when you do have a
|
|
118
|
+
* choice; sp_crypto_hmac_sha256_hex is the right primitive. */
|
|
119
|
+
const char *sp_crypto_hmac_sha1_hex(const char *key, const char *msg);
|
|
120
|
+
|
|
121
|
+
/* Base64URL (RFC 4648 §5, no padding) encode/decode. Max input
|
|
122
|
+
* length ~12 KiB (encode) / ~16 KiB (decode), bump the buffer in
|
|
123
|
+
* sp_crypto.c if your callers need more. The decode answers bytes that
|
|
124
|
+
* may hold a NUL and sets sp_ffi_bin_len to their count (0 on bad input):
|
|
125
|
+
* bind it `:binstr`, as a `:str` return stops at the first NUL. */
|
|
126
|
+
const char *sp_crypto_b64url_encode(const char *src);
|
|
127
|
+
const char *sp_crypto_b64url_decode(const char *src);
|
|
128
|
+
|
|
129
|
+
/* PBKDF2-HMAC-SHA256(password, salt, iters) -> 43-char unpadded
|
|
130
|
+
* base64url (32 bytes derived -- the one-block case). */
|
|
131
|
+
const char *sp_crypto_pbkdf2_sha256_b64url(const char *password, const char *salt, int iters);
|
|
132
|
+
|
|
133
|
+
/* Same, with an explicit derived length in BYTES (clamped to [1, 64]);
|
|
134
|
+
* 64 bytes -> 86 unpadded b64url chars. Rails derives its signed-cookie
|
|
135
|
+
* and signed-id keys at dkLen 64 (ActiveSupport::KeyGenerator#
|
|
136
|
+
* generate_key's default key_size), so a spinel program that reads or
|
|
137
|
+
* mints one needs the two-block form. */
|
|
138
|
+
const char *sp_crypto_pbkdf2_sha256_b64url_len(const char *password, const char *salt,
|
|
139
|
+
int iters, int dklen);
|
|
140
|
+
|
|
141
|
+
/* Largest single draw the raw-bytes entry point below serves. Covers
|
|
142
|
+
* every SecureRandom shape a program reaches for (a v4 uuid is 16, a
|
|
143
|
+
* session token 24, a 256-bit key 32); a larger request is an
|
|
144
|
+
* ArgumentError rather than a silently short answer. */
|
|
145
|
+
#define SPC_RANDOM_MAX 256
|
|
146
|
+
|
|
147
|
+
/* nbytes raw CSPRNG bytes, with the count published in sp_ffi_bin_len
|
|
148
|
+
* for the `:cbinstr` return mode (random bytes contain NULs). Uses
|
|
149
|
+
* arc4random_buf on BSD/macOS; on Linux/POSIX getrandom(2), then
|
|
150
|
+
* /dev/urandom. RAISES when no secure source is available -- a caller
|
|
151
|
+
* asking for random bytes is minting a token, and there is no answer
|
|
152
|
+
* to give. The bundled `securerandom` package binds this. */
|
|
153
|
+
/* Fill `out` with `nbytes` of kernel-sourced entropy. 1 on success, 0 when
|
|
154
|
+
there is no secure source -- callers fail closed rather than fall back to
|
|
155
|
+
weak randomness. The one place that decides what counts as secure. */
|
|
156
|
+
int sp_crypto_entropy(unsigned char *out, int nbytes);
|
|
157
|
+
const char *sp_crypto_random_bin(int nbytes);
|
|
158
|
+
|
|
159
|
+
/* CSPRNG: nbytes random bytes (clamped to [1, 64]) as unpadded
|
|
160
|
+
* base64url. Uses arc4random_buf on BSD/macOS; on Linux/POSIX
|
|
161
|
+
* getrandom(2), then /dev/urandom. Returns NULL when no secure source
|
|
162
|
+
* is available (fails closed -- never degrades to weak randomness). */
|
|
163
|
+
const char *sp_crypto_random_b64url(int nbytes);
|
|
164
|
+
|
|
165
|
+
#ifdef __cplusplus
|
|
166
|
+
}
|
|
167
|
+
#endif
|
|
168
|
+
|
|
169
|
+
#endif /* SP_CRYPTO_H */
|