Skip to content

Commit f0d33e5

Browse files
committed
FEAT: form-oid function for conversion of OID binary value into its numeric string format
1 parent 5868c1d commit f0d33e5

File tree

4 files changed

+184
-8
lines changed

4 files changed

+184
-8
lines changed

make/rebol3.nest

+3
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,8 @@ include-prot-mysql: [mezz-prot-files: %mezz/prot-mysql.reb ]
701701

702702
include-prebol: [mezz-lib-files: %modules/prebol.reb ]
703703

704+
include-native-oid: [core-files: %core/n-oid.c] ; `form-oid` native (used in DER codec)
705+
704706
include-https: [
705707
:include-bincode
706708
:include-cryptography
@@ -770,6 +772,7 @@ include-rebol-bulk: [
770772
:include-prot-mysql
771773

772774
:include-dialecting ;`delect`
775+
:include-native-oid ;`form-oid`
773776

774777
config: INCLUDE_PNG_FILTER ; includes `filter` and `unfilter` natives
775778

src/core/n-oid.c

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/***********************************************************************
2+
**
3+
** REBOL [R3] Language Interpreter and Run-time Environment
4+
**
5+
** Copyright 2012 REBOL Technologies
6+
** Copyright 2012-2022 Rebol Open Source Contributors
7+
** REBOL is a trademark of REBOL Technologies
8+
**
9+
** Licensed under the Apache License, Version 2.0 (the "License");
10+
** you may not use this file except in compliance with the License.
11+
** You may obtain a copy of the License at
12+
**
13+
** http://www.apache.org/licenses/LICENSE-2.0
14+
**
15+
** Unless required by applicable law or agreed to in writing, software
16+
** distributed under the License is distributed on an "AS IS" BASIS,
17+
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
** See the License for the specific language governing permissions and
19+
** limitations under the License.
20+
**
21+
************************************************************************
22+
**
23+
** Module: n-oid.c
24+
** Summary: native function for object identifiers (OID)
25+
** Section: natives
26+
** Author: Oldes
27+
** Notes: Based on code from mbedTLS
28+
**
29+
***********************************************************************/
30+
31+
#include <stdio.h>
32+
#include "sys-core.h"
33+
34+
/***********************************************************************
35+
**
36+
*/ REBNATIVE(form_oid)
37+
/*
38+
// form-oid: native [
39+
// "Return the x.y.z.... style numeric string for the given OID"
40+
// oid [binary!]
41+
// ]
42+
***********************************************************************/
43+
{
44+
REBVAL *val_oid = D_ARG(1);
45+
REBSER *out;
46+
REBYTE *oid;
47+
REBCNT len, value;
48+
int ret = 0;
49+
size_t i, n;
50+
char *p;
51+
52+
oid = VAL_BIN_AT(val_oid);
53+
len = VAL_LEN(val_oid);
54+
out = Make_Binary(3 * len); // len * 3 should be enough to hold the result
55+
p = SERIES_DATA(out);
56+
n = SERIES_AVAIL(out);
57+
58+
if (len > 0) {
59+
ret = snprintf(p, n, "%d.%d", oid[0] / 40, oid[0] % 40);
60+
//Minimal series is 8 bytes so it must be enough to hold first 2 integers
61+
//if (ret >= n) {
62+
// Extend_Series(out, ret - n + 1); // may reallocate p!
63+
// p = SERIES_DATA(out) + SERIES_TAIL(out);
64+
// n = SERIES_REST(out) - SERIES_TAIL(out);
65+
// ret = snprintf(p, n, "%d.%d", oid[0] / 40, oid[0] % 40);
66+
//}
67+
if (ret < 0) return R_ARG1; // error!
68+
SERIES_TAIL(out) += ret;
69+
n -= (size_t)ret;
70+
p += (size_t)ret;
71+
}
72+
73+
value = 0;
74+
for (i = 1; i < len; i++) {
75+
/* Prevent overflow in value. */
76+
if (((value << 7) >> 7) != value)
77+
return R_ARG1; // error!
78+
79+
value <<= 7;
80+
value += oid[i] & 0x7F;
81+
82+
if (!(oid[i] & 0x80)) {
83+
/* Last byte */
84+
ret = snprintf(p, n, ".%u", value);
85+
if (ret >= n) {
86+
Extend_Series(out, ret - n + 1); // may reallocate p!
87+
p = SERIES_DATA(out) + SERIES_TAIL(out);
88+
n = SERIES_AVAIL(out);
89+
ret = snprintf(p, n, ".%u", value);
90+
}
91+
if (ret < 0) return R_ARG1; // error!
92+
SERIES_TAIL(out) += ret;
93+
n -= (size_t)ret;
94+
p += (size_t)ret;
95+
value = 0;
96+
}
97+
}
98+
SET_STRING(D_RET, out);
99+
return R_RET;
100+
}

src/mezz/codec-der.reb

+73-8
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ REBOL [
22
title: "REBOL3 codec for DER/BER structures"
33
name: 'codec-der
44
author: "Oldes"
5-
version: 0.1.0
6-
date: 17-Oct-2018
5+
version: 0.2.0
6+
date: 17-Feb-2022
77
history: [
88
0.1.0 17-Oct-2018 "Oldes" {Initial version with DECODE and IDENTIFY functions.}
9+
0.2.0 17-Feb-2022 "Oldes" {Including `form-id`}
910
]
1011
notes: {
1112
Useful command for cross-testing:
@@ -198,7 +199,33 @@ register-codec [
198199
BMP_STRING ;= 1e Basic Multilingual Plane/Unicode string
199200
]
200201

202+
form-OID: either find lib 'form-oid [
203+
; native version
204+
:lib/form-oid
205+
][
206+
function[
207+
"Return the x.y.z.... style numeric string for the given OID"
208+
oid [binary!]
209+
][
210+
len: length? oid
211+
out: make string! 3 * len
212+
append out ajoin [to integer! oid/1 / 40 #"." oid/1 % 40]
213+
++ oid
214+
value: 0
215+
while [not tail? oid][
216+
value: (value << 7)
217+
value: value + (oid/1 & 127)
218+
if oid/1 & 128 = 0 [
219+
append append out #"." value
220+
value: 0
221+
]
222+
++ oid
223+
]
224+
out
225+
]
226+
]
201227
decode-OID: function[
228+
"Convert given OID to its name if recognized or a numeric string"
202229
oid [binary!]
203230
/full "Returns name with group name as a string"
204231
/local main name warn
@@ -237,10 +264,16 @@ register-codec [
237264
;| #"^(03)" (name: 'prime192v3)
238265
| #"^(01)" (name: 'secp192r1)
239266
]
267+
| #{0403} [
268+
#"^(01)" (name: 'ecdsa-with-SHA224)
269+
| #"^(02)" (name: 'ecdsa-with-SHA256)
270+
| #"^(03)" (name: 'ecdsa-with-SHA384)
271+
| #"^(04)" (name: 'ecdsa-with-SHA512)
272+
]
240273
]
241274
|
242275
#{2A864886F70D01} [
243-
#{01} (main: "PKCS #1") [
276+
#"^(01)" (main: "PKCS #1") [
244277
#"^(01)" (name: 'rsaEncryption)
245278
| #"^(02)" (name: 'md2WithRSAEncryption)
246279
| #"^(03)" (name: 'md4withRSAEncryption)
@@ -252,13 +285,13 @@ register-codec [
252285

253286
] end
254287
|
255-
#{07} (main: "PKCS #7") [
288+
#"^(07)" (main: "PKCS #7") [
256289
#"^(01)" (name: 'data)
257290
| #"^(02)" (name: 'signedData)
258291
| #"^(06)" (name: 'encryptedData)
259292
] end
260293
|
261-
#{09} (main: "PKCS #9") [
294+
#"^(09)" (main: "PKCS #9") [
262295
;http://oid-info.com/get/1.2.840.113549.1.9
263296
#"^(01)" (name: 'emailAddress warn: "Deprecated, use an altName extension instead")
264297
| #"^(03)" (name: 'contentType)
@@ -270,7 +303,7 @@ register-codec [
270303
| #"^(34)" (name: 'CMSAlgorithmProtect)
271304
] end
272305
|
273-
#{0C} (main: "PKCS #12") [
306+
#"^(0C)" (main: "PKCS #12") [
274307
#{0106} (name: 'pbeWithSHAAnd40BitRC2-CBC)
275308
| #{0103} (name: 'pbeWithSHAAnd3-KeyTripleDES-CBC)
276309
| #{0A0102} (name: 'pkcs-12-pkcs-8ShroudedKeyBag)
@@ -312,8 +345,40 @@ register-codec [
312345
|
313346
#{2B060105050703} (main: "PKIX key purpose") [
314347
#"^(01)" (name: 'serverAuth)
315-
#"^(02)" (name: 'clientAuth)
348+
| #"^(02)" (name: 'clientAuth)
316349
| #"^(03)" (name: 'codeSigning)
350+
| #"^(04)" (name: 'emailProtection)
351+
;| #"^(05)" (name: 'ipsecEndSystem)
352+
;| #"^(06)" (name: 'ipsecTunnel)
353+
;| #"^(07)" (name: 'ipsecUser)
354+
| #"^(08)" (name: 'timeStamping)
355+
;| #"^(09)" (name: 'OCSPSigning)
356+
;| #"^(0A)" (name: 'dvcs)
357+
;| #"^(0B)" (name: 'sbgpCertAAServerAuth)
358+
;| #"^(0C)" (name: 'scvp)
359+
;| #"^(0D)" (name: 'eapOverPPP)
360+
;| #"^(0E)" (name: 'eapOverLAN)
361+
;| #"^(0F)" (name: 'scvpServer)
362+
;| #"^(10)" (name: 'scvpClient)
363+
;| #"^(11)" (name: 'ipsecIKE)
364+
;| #"^(12)" (name: 'capwapAC)
365+
;| #"^(13)" (name: 'capwapWTP)
366+
;| #"^(14)" (name: 'sipDomain)
367+
;| #"^(15)" (name: 'secureShellClient)
368+
;| #"^(16)" (name: 'secureShellServer)
369+
;| #"^(17)" (name: 'sendRouter)
370+
;| #"^(18)" (name: 'sendProxiedRouter)
371+
;| #"^(19)" (name: 'sendOwner)
372+
;| #"^(1A)" (name: 'sendProxiedOwner)
373+
;| #"^(1B)" (name: 'cmcCA)
374+
;| #"^(1C)" (name: 'cmcRA)
375+
;| #"^(1D)" (name: 'cmcArchive)
376+
;| #"^(1E)" (name: 'bgpsec-router)
377+
;| #"^(1F)" (name: 'BrandIndicatorforMessageIdentification)
378+
;| #"^(20)" (name: 'cmKGA)
379+
;| #"^(21)" (name: 'rpcTLSClient)
380+
;| #"^(22)" (name: 'rpcTLSServer)
381+
;| #"^(23)" (name: 'bundleSecurity)
317382
] end
318383
|
319384
#{2B0601040182370201} (main: "Microsoft") [
@@ -328,7 +393,7 @@ register-codec [
328393
either full [
329394
rejoin [ any [name "<?name>"] " (" any [main "<?main>"] ")"]
330395
][ name ]
331-
][ oid ]
396+
][ form-oid oid ]
332397
]
333398

334399
verbose: 0

src/tests/units/codecs-test.r3

+8
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,14 @@ if find codecs 'der [
199199
--assert binary? try [c: b/sequence/sequence/4/2]
200200
--assert block? d: decode 'DER c
201201

202+
--test-- "form-OID"
203+
--assert "2.5.29.17" = codecs/der/form-oid #{551D11}
204+
--assert "1.2.840.10045.4.3.2" = codecs/der/form-oid #{2A8648CE3D040302}
205+
206+
--test-- "decode-OID"
207+
--assert 'subjectAltName = codecs/der/decode-oid #{551D11}
208+
--assert 'ecdsa-with-SHA256 = codecs/der/decode-oid #{2A8648CE3D040302}
209+
202210
===end-group===
203211
codecs/der/verbose: 0
204212
]

0 commit comments

Comments
 (0)