Subversion Repositories oidplus

Rev

Rev 979 | Rev 1052 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
635 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
929 daniel-mar 5
 * Copyright 2019 - 2022 Daniel Marschall, ViaThinkSoft
635 daniel-mar 6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
1050 daniel-mar 20
namespace ViaThinkSoft\OIDplus;
635 daniel-mar 21
 
22
class OIDplusOid extends OIDplusObject {
23
        private $oid;
24
 
25
        public function __construct($oid) {
26
                $bak_oid = $oid;
27
 
28
                $oid = sanitizeOID($oid, 'auto');
29
                if ($oid === false) {
30
                        throw new OIDplusException(_L('Invalid OID %1',$bak_oid));
31
                }
32
 
33
                if (($oid != '') && (!oid_valid_dotnotation($oid, false, true, 0))) {
34
                        // avoid OIDs like 3.0
35
                        throw new OIDplusException(_L('Invalid OID %1',$bak_oid));
36
                }
37
 
38
                $this->oid = $oid;
39
        }
40
 
41
        public static function parse($node_id) {
42
                @list($namespace, $oid) = explode(':', $node_id, 2);
860 daniel-mar 43
                if ($namespace !== self::ns()) return false;
635 daniel-mar 44
                return new self($oid);
45
        }
46
 
47
        public static function objectTypeTitle() {
48
                return _L('Object Identifier (OID)');
49
        }
50
 
51
        public static function objectTypeTitleShort() {
52
                return _L('OID');
53
        }
54
 
55
        public static function ns() {
56
                return 'oid';
57
        }
58
 
59
        public static function root() {
860 daniel-mar 60
                return self::ns().':';
635 daniel-mar 61
        }
62
 
63
        public function isRoot() {
64
                return $this->oid == '';
65
        }
66
 
67
        public function nodeId($with_ns=true) {
859 daniel-mar 68
                return $with_ns ? self::root().$this->oid : $this->oid;
635 daniel-mar 69
        }
70
 
71
        public function addString($str) {
72
                if (!$this->isRoot()) {
73
                        if (strpos($str,'.') !== false) throw new OIDplusException(_L('Please only submit one arc (not an absolute OID or multiple arcs).'));
74
                }
75
 
76
                return $this->appendArcs($str)->nodeId();
77
        }
78
 
79
        public function crudShowId(OIDplusObject $parent) {
80
                if ($parent instanceof OIDplusOid) {
81
                        return $this->deltaDotNotation($parent);
82
                }
83
        }
84
 
85
        public function jsTreeNodeName(OIDplusObject $parent = null) {
86
                if ($parent == null) return $this->objectTypeTitle();
87
                if ($parent instanceof OIDplusOid) {
88
                        return $this->viewGetArcAsn1s($parent);
89
                } else {
90
                        return '';
91
                }
92
        }
93
 
94
        public function defaultTitle() {
95
                return _L('OID %1',$this->oid);
96
        }
97
 
98
        public function isLeafNode() {
99
                return false;
100
        }
101
 
753 daniel-mar 102
        private function getTechInfo() {
103
                $tech_info = array();
104
 
105
                $tmp = _L('Dot notation');
106
                $tmp = str_replace(explode(' ', $tmp, 2)[0], '<a href="http://oid-info.com/faq.htm#14" target="_blank">'.explode(' ', $tmp, 2)[0].'</a>', $tmp);
107
                $tech_info[$tmp] = $this->getDotNotation();
108
 
109
                $tmp = _L('ASN.1 notation');
110
                $tmp = str_replace(explode(' ', $tmp, 2)[0], '<a href="http://oid-info.com/faq.htm#17" target="_blank">'.explode(' ', $tmp, 2)[0].'</a>', $tmp);
111
                $tech_info[$tmp] = $this->getAsn1Notation();
112
 
113
                $tmp = _L('OID-IRI notation');
114
                $tmp = str_replace(explode(' ', $tmp, 2)[0], '<a href="http://oid-info.com/faq.htm#iri" target="_blank">'.explode(' ', $tmp, 2)[0].'</a>', $tmp);
115
                $tech_info[$tmp] = $this->getIriNotation();
116
 
117
                $tmp = _L('WEID notation');
118
                $tmp = str_replace(explode(' ', $tmp, 2)[0], '<a href="https://weid.info/" target="_blank">'.explode(' ', $tmp, 2)[0].'</a>', $tmp);
119
                $tech_info[$tmp] = $this->getWeidNotation();
120
 
930 daniel-mar 121
                $tmp = _L('DER encoding');
122
                $tmp = str_replace(explode(' ', $tmp, 2)[0], '<a href="https://misc.daniel-marschall.de/asn.1/oid-converter/online.php" target="_blank">'.explode(' ', $tmp, 2)[0].'</a>', $tmp);
1050 daniel-mar 123
                $tech_info[$tmp] = str_replace(' ', ':', \OidDerConverter::hexarrayToStr(\OidDerConverter::oidToDER($this->nodeId(false))));
930 daniel-mar 124
 
753 daniel-mar 125
                return $tech_info;
126
        }
127
 
772 daniel-mar 128
        protected function isClassCWeid() {
129
                $dist = oid_distance($this->oid, '1.3.6.1.4.1.37553.8');
130
                if ($dist === false) return false;
131
                return $dist >= 0;
132
        }
133
 
635 daniel-mar 134
        public function getContentPage(&$title, &$content, &$icon) {
772 daniel-mar 135
                if ($this->isClassCWeid()) {
136
                        // TODO: Also change treeview menu mini-icon?
801 daniel-mar 137
                        $icon = file_exists(__DIR__.'/img/weid_icon.png') ? OIDplus::webpath(__DIR__,OIDplus::PATH_RELATIVE).'img/weid_icon.png' : '';
772 daniel-mar 138
                } else {
801 daniel-mar 139
                        $icon = file_exists(__DIR__.'/img/main_icon.png') ? OIDplus::webpath(__DIR__,OIDplus::PATH_RELATIVE).'img/main_icon.png' : '';
772 daniel-mar 140
                }
635 daniel-mar 141
 
142
                if ($this->isRoot()) {
143
                        $title = OIDplusOid::objectTypeTitle();
144
 
145
                        $res = OIDplus::db()->query("select id from ###objects where parent = ?", array(self::root()));
790 daniel-mar 146
                        if ($res->any()) {
635 daniel-mar 147
                                $content = _L('Please select an OID in the tree view at the left to show its contents.');
148
                        } else {
149
                                $content = _L('Currently, no OID is registered in the system.');
150
                        }
151
 
152
                        if (!$this->isLeafNode()) {
153
                                if (OIDplus::authUtils()->isAdminLoggedIn()) {
154
                                        $content .= '<h2>'._L('Manage your root OIDs').'</h2>';
155
                                } else {
156
                                        $content .= '<h2>'._L('Root OIDs').'</h2>';
157
                                }
158
                                $content .= '%%CRUD%%';
159
                        }
160
                } else {
161
                        $title = $this->getTitle();
162
 
753 daniel-mar 163
                        $tech_info = $this->getTechInfo();
164
                        $tech_info_html = '';
165
                        if (count($tech_info) > 0) {
166
                                $tech_info_html .= '<h2>'._L('Technical information').'</h2>';
167
                                $tech_info_html .= '<table border="0">';
168
                                foreach ($tech_info as $key => $value) {
169
                                        $tech_info_html .= '<tr><td>'.$key.': </td><td><code>'.$value.'</code></td></tr>';
170
                                }
171
                                $tech_info_html .= '</table>';
172
                        }
635 daniel-mar 173
 
753 daniel-mar 174
                        $content = $tech_info_html;
175
 
176
                        $content .= '<h2>'._L('Description').'</h2>%%DESC%%'.
177
                                    '<h2>'._L('Registration Authority').'</h2>%%RA_INFO%%';
178
 
635 daniel-mar 179
                        if (!$this->isLeafNode()) {
180
                                if ($this->userHasWriteRights()) {
928 daniel-mar 181
                                        $content .= '<h2>'._L('Create or change subordinate objects').'</h2>';
635 daniel-mar 182
                                } else {
928 daniel-mar 183
                                        $content .= '<h2>'._L('Subordinate objects').'</h2>';
635 daniel-mar 184
                                }
185
                                $content .= '%%CRUD%%';
186
                        }
187
                }
188
        }
189
 
190
        # ---
191
 
683 daniel-mar 192
        // Gets the last arc of an WEID
635 daniel-mar 193
        public function weidArc() {
689 daniel-mar 194
                // Dirty hack: We prepend '0.' in front of the OID to enforce the
195
                //             creation of a Class A weid (weid:root:) . Otherwise we could not
196
                //             get the hidden arc value "8" from "weid:4" (which is actually "weid:pen:SZ5-8-?"
1050 daniel-mar 197
                $weid = \Frdl\Weid\WeidOidConverter::oid2weid('0.'.$this->getDotNotation());
635 daniel-mar 198
                if ($weid === false) return false;
683 daniel-mar 199
                $ary = explode(':', $weid);
200
                $weid = array_pop($ary); // remove namespace and sub-namespace if existing
635 daniel-mar 201
                $x = explode('-', $weid);
202
                if (count($x) < 2) return ''; // WEID root arc. Has no name
203
                return $x[count($x)-2];
204
        }
205
 
206
        public function getWeidNotation($withAbbr=true) {
1050 daniel-mar 207
                $weid = \Frdl\Weid\WeidOidConverter::oid2weid($this->getDotNotation());
635 daniel-mar 208
                if ($withAbbr) {
683 daniel-mar 209
                        $ary = explode(':', $weid);
210
                        $weid = array_pop($ary); // remove namespace and sub-namespace if existing
211
                        $ns = implode(':', $ary).':';
212
 
635 daniel-mar 213
                        $weid_arcs = explode('-', $weid);
214
                        foreach ($weid_arcs as $i => &$weid) {
215
                                if ($i == count($weid_arcs)-1) {
216
                                        $weid = '<abbr title="'._L('weLuhn check digit').'">'.$weid.'</abbr>';
217
                                } else {
218
                                        $oid_arcs = explode('.',$this->oid);
219
                                        $weid_num = $oid_arcs[(count($oid_arcs)-1)-(count($weid_arcs)-1)+($i+1)];
220
                                        if ($weid_num != $weid) {
221
                                                $weid = '<abbr title="'._L('Numeric value').': '.$weid_num.'">'.$weid.'</abbr>';
222
                                        }
223
                                }
224
                        }
683 daniel-mar 225
                        $base_arc = '???';
226
                        if ($ns === 'weid:')      $base_arc = '1.3.6.1.4.1.37553.8';
227
                        if ($ns === 'weid:pen:')  $base_arc = '1.3.6.1.4.1';
688 daniel-mar 228
                        if ($ns === 'weid:root:') $base_arc = _L('OID tree root');
683 daniel-mar 229
 
230
                        $weid = '<abbr title="'._L('Base OID').': '.$base_arc.'">' . rtrim($ns,':') . '</abbr>:' . implode('-',$weid_arcs);
635 daniel-mar 231
                }
232
                return $weid;
233
        }
234
 
235
        public function appendArcs(String $arcs) {
236
                $out = new self($this->oid);
237
 
238
                if ($out->isRoot()) {
239
                        $out->oid .= $arcs;
240
                } else {
241
                        $out->oid .= '.' . $arcs;
242
                }
243
 
244
                $bak_oid = $out->oid;
245
                $out->oid = sanitizeOID($out->oid);
246
                if ($out->oid === false) throw new OIDplusException(_L('%1 is not a valid OID!',$bak_oid));
247
 
859 daniel-mar 248
                $maxlen = OIDplus::baseConfig()->getValue('LIMITS_MAX_ID_LENGTH')-strlen(self::root());
635 daniel-mar 249
                if (strlen($out->oid) > $maxlen) {
250
                        throw new OIDplusException(_L('The resulting OID "%1" is too long (max allowed length: %2).',$out->oid,$maxlen));
251
                }
252
 
253
                $depth = 0;
254
                foreach (explode('.',$out->oid) as $arc) {
255
                        if (strlen($arc) > OIDplus::baseConfig()->getValue('LIMITS_MAX_OID_ARC_SIZE')) {
256
                                $maxlen = OIDplus::baseConfig()->getValue('LIMITS_MAX_OID_ARC_SIZE');
257
                                throw new OIDplusException(_L('Arc "%1" is too long and therefore cannot be appended to the OID "%2" (max allowed arc size is "%3")',$arc,$this->oid,$maxlen));
258
                        }
259
                        $depth++;
260
                }
261
                if ($depth > OIDplus::baseConfig()->getValue('LIMITS_MAX_OID_DEPTH')) {
262
                        $maxdepth = OIDplus::baseConfig()->getValue('LIMITS_MAX_OID_DEPTH');
263
                        throw new OIDplusException(_L('OID %1 has too many arcs (current depth %2, max depth %3)',$out->oid,$depth,$maxdepth));
264
                }
265
 
266
                return $out;
267
        }
268
 
269
        public function deltaDotNotation(OIDplusOid $parent) {
270
                if (!$parent->isRoot()) {
271
                        if (substr($this->oid, 0, strlen($parent->oid)+1) == $parent->oid.'.') {
272
                                return substr($this->oid, strlen($parent->oid)+1);
273
                        } else {
274
                                return false;
275
                        }
276
                } else {
277
                        return $this->oid;
278
                }
279
        }
280
 
979 daniel-mar 281
        public function getAsn1Ids() {
282
                $asn_ids = array();
283
                $res_asn = OIDplus::db()->query("select * from ###asn1id where oid = ? order by lfd", array("oid:".$this->oid));
284
                while ($row_asn = $res_asn->fetch_array()) {
285
                        $name = $row_asn['name'];
286
                        $standardized = $row_asn['standardized'];
287
                        $well_known = $row_asn['well_known'];
288
                        $asn_ids[] = new OIDplusOidAsn1Id($name, $standardized, $well_known);
289
                }
290
                return $asn_ids;
291
        }
292
 
293
        public function getIris() {
294
                $iri_ids = array();
295
                $res_iri = OIDplus::db()->query("select * from ###iri where oid = ? order by lfd", array("oid:".$this->oid));
296
                while ($row_iri = $res_iri->fetch_array()) {
297
                        $name = $row_iri['name'];
298
                        $longarc = $row_iri['longarc'];
299
                        $well_known = $row_iri['well_known'];
300
                        $iri_ids[] = new OIDplusOidIri($name, $longarc, $well_known);
301
                }
302
                return $iri_ids;
303
        }
304
 
635 daniel-mar 305
        public function viewGetArcAsn1s(OIDplusOid $parent=null, $separator = ' | ') {
306
                $asn_ids = array();
307
 
859 daniel-mar 308
                if (is_null($parent)) $parent = OIDplusOid::parse(self::root());
635 daniel-mar 309
 
310
                $part = $this->deltaDotNotation($parent);
311
 
312
                if (strpos($part, '.') === false) {
979 daniel-mar 313
                        $asn_id_objs = $this->getAsn1Ids();
314
                        foreach ($asn_id_objs as $asn_id_obj) {
315
                                $asn_ids[] = $asn_id_obj->getName().'('.$part.')';
635 daniel-mar 316
                        }
317
                }
318
 
319
                if (count($asn_ids) == 0) $asn_ids = array($part);
320
                return implode($separator, $asn_ids);
321
        }
322
 
323
        public function getAsn1Notation($withAbbr=true) {
324
                $asn1_notation = '';
325
                $arcs = explode('.', $this->oid);
326
 
327
                foreach ($arcs as $arc) {
859 daniel-mar 328
                        $res = OIDplus::db()->query("select name, standardized from ###asn1id where oid = ? order by lfd", array(self::root().implode('.',$arcs)));
635 daniel-mar 329
 
330
                        $names = array();
331
                        while ($row = $res->fetch_array()) {
332
                                $names[] = $row['name']."(".end($arcs).")";
333
                                if ($row['standardized']) {
334
                                        $names[] = $row['name'];
335
                                }
336
                        }
337
 
338
                        $numeric = array_pop($arcs);
339
                        if (count($names) > 1) {
340
                                $first_name = array_shift($names);
341
                                $abbr = _L('Other identifiers').':&#10;      '.implode('&#10;      ',$names);
342
                                if ($withAbbr) {
343
                                        $asn1_notation = '<abbr title="'.$abbr.'">'.$first_name.'</abbr> '.$asn1_notation;
344
                                } else {
345
                                        $asn1_notation = $first_name.' '.$asn1_notation;
346
                                }
347
                        } else if (count($names) == 1) {
348
                                $asn1_notation = array_shift($names).' '.$asn1_notation;
349
                        } else {
350
                                $asn1_notation = $numeric.' '.$asn1_notation;
351
                        }
352
                }
353
 
758 daniel-mar 354
                return "{ ".trim($asn1_notation)." }";
635 daniel-mar 355
        }
356
 
357
        public function getIriNotation($withAbbr=true) {
358
                $iri_notation = '';
359
                $arcs = explode('.', $this->oid);
360
 
361
                foreach ($arcs as $arc) {
859 daniel-mar 362
                        $res = OIDplus::db()->query("select name, longarc from ###iri where oid = ? order by lfd", array(self::root().implode('.',$arcs)));
635 daniel-mar 363
 
364
                        $is_longarc = false;
365
                        $names = array();
366
                        while ($row = $res->fetch_array()) {
367
                                $is_longarc = $row['longarc'];
368
                                $names[] = $row['name'];
369
 
370
                                if ($is_longarc) {
371
                                        $names[] = 'Joint-ISO-ITU-T/'.$row['name']; // Long arcs can only be inside root OID 2
372
                                }
373
                        }
374
 
375
                        $names[] = array_pop($arcs);
376
                        if (count($names) > 2) {
377
                                $first_name = array_shift($names);
378
                                $numeric = array_pop($names);
379
                                $abbr = _L('Other identifiers').':&#10;      '.implode('&#10;      ',$names).'&#10;'._L('Numeric value').': '.$numeric;
380
                                $iri_notation = $withAbbr ? '<abbr title="'.$abbr.'">'.$first_name.'</abbr>/'.$iri_notation : $first_name.'/'.$iri_notation;
381
                        } else if (count($names) > 1) {
382
                                $first_name = array_shift($names);
383
                                $abbr = _L('Numeric value').': '.array_shift($names);
384
                                $iri_notation = $withAbbr ? '<abbr title="'.$abbr.'">'.$first_name.'</abbr>/'.$iri_notation : $first_name.'/'.$iri_notation;
385
                        } else if (count($names) == 1) {
386
                                $iri_notation = array_shift($names) . '/' . $iri_notation;
387
                        }
388
 
389
                        if ($is_longarc) break; // we don't write /ITU-T/ at the beginning, when /ITU-T/xyz is a long arc
390
                }
391
                $iri_notation = '/' . substr($iri_notation, 0, strlen($iri_notation)-1);
392
 
393
                return $iri_notation;
394
        }
395
 
396
        public function getDotNotation() {
397
                return $this->oid;
398
        }
399
 
400
        public function isWellKnown() {
401
                $res = OIDplus::db()->query("select oid from ###asn1id where oid = ? and well_known = ?", array("oid:".$this->oid,true));
790 daniel-mar 402
                if ($res->any()) return true;
635 daniel-mar 403
 
404
                $res = OIDplus::db()->query("select oid from ###iri where oid = ? and well_known = ?", array("oid:".$this->oid,true));
790 daniel-mar 405
                if ($res->any()) return true;
635 daniel-mar 406
 
407
                return false;
408
        }
409
 
410
        public function replaceAsn1Ids($demandedASN1s=array(), $simulate=false) {
411
                if ($this->isWellKnown()) {
412
                        throw new OIDplusException(_L('OID "%1" is a "well-known" OID. Its identifiers cannot be changed.',$this->oid));
413
                }
414
 
415
                // First do a few checks
416
                foreach ($demandedASN1s as &$asn1) {
417
                        $asn1 = trim($asn1);
418
 
419
                        if (strlen($asn1) > OIDplus::baseConfig()->getValue('LIMITS_MAX_OID_ASN1_ID_LEN')) {
420
                                $maxlen = OIDplus::baseConfig()->getValue('LIMITS_MAX_OID_ASN1_ID_LEN');
421
                                throw new OIDplusException(_L('ASN.1 alphanumeric identifier "%1" is too long (max allowed length %2)',$asn1,$maxlen));
422
                        }
423
 
424
                        // Validate identifier
425
                        if (!oid_id_is_valid($asn1)) throw new OIDplusException(_L('"%1" is not a valid ASN.1 identifier!',$asn1));
426
 
427
                        // Check if the (real) parent has any conflict
428
                        // Unlike IRI identifiers, ASN.1 identifiers may be used multiple times (not recommended), except if one of them is standardized
429
                        $res = OIDplus::db()->query("select oid from ###asn1id where name = ? and standardized = ?", array($asn1,true));
430
                        while ($row = $res->fetch_array()) {
431
                                $check_oid = OIDplusOid::parse($row['oid'])->oid;
432
                                if ((oid_up($check_oid) === oid_up($this->oid)) && // same parent
433
                                   ($check_oid !== $this->oid))                    // different OID
434
                                {
435
                                        throw new OIDplusException(_L('ASN.1 identifier "%1" is a standardized identifier belonging to OID %2',$asn1,$check_oid));
436
                                }
437
                        }
438
                }
439
 
440
                // Now do the real replacement
441
                if (!$simulate) {
442
                        OIDplus::db()->query("delete from ###asn1id where oid = ?", array("oid:".$this->oid));
443
                        foreach ($demandedASN1s as &$asn1) {
444
                                OIDplus::db()->query("insert into ###asn1id (oid, name) values (?, ?)", array("oid:".$this->oid, $asn1));
445
                        }
446
                }
447
        }
448
 
449
        public function replaceIris($demandedIris=array(), $simulate=false) {
450
                if ($this->isWellKnown()) {
451
                        throw new OIDplusException(_L('OID "%1" is a "well-known" OID. Its identifiers cannot be changed.',$this->oid));
452
                }
453
 
454
                // First do a few checks
455
                foreach ($demandedIris as &$iri) {
456
                        $iri = trim($iri);
457
 
458
                        if (strlen($iri) > OIDplus::baseConfig()->getValue('LIMITS_MAX_OID_UNICODE_LABEL_LEN')) {
459
                                $maxlen = OIDplus::baseConfig()->getValue('LIMITS_MAX_OID_UNICODE_LABEL_LEN');
460
                                throw new OIDplusException(_L('Unicode label "%1" is too long (max allowed length %2)',$iri,$maxlen));
461
                        }
462
 
463
                        // Validate identifier
464
                        if (!iri_arc_valid($iri, false)) throw new OIDplusException(_L('"%1" is not a valid IRI!',$iri));
465
 
466
                        // Check if the (real) parent has any conflict
467
                        $res = OIDplus::db()->query("select oid from ###iri where name = ?", array($iri));
468
                        while ($row = $res->fetch_array()) {
469
                                $check_oid = OIDplusOid::parse($row['oid'])->oid;
470
                                if ((oid_up($check_oid) === oid_up($this->oid)) && // same parent
471
                                   ($check_oid !== $this->oid))                    // different OID
472
                                {
473
                                        throw new OIDplusException(_L('IRI "%1" is already used by another OID (%2)',$iri,$check_oid));
474
                                }
475
                        }
476
                }
477
 
478
                // Now do the real replacement
479
                if (!$simulate) {
480
                        OIDplus::db()->query("delete from ###iri where oid = ?", array("oid:".$this->oid));
481
                        foreach ($demandedIris as &$iri) {
482
                                OIDplus::db()->query("insert into ###iri (oid, name) values (?, ?)", array("oid:".$this->oid, $iri));
483
                        }
484
                }
485
        }
486
 
487
        public function one_up() {
488
                return self::parse(self::ns().':'.oid_up($this->oid));
489
        }
490
 
491
        public function distance($to) {
492
                if (!is_object($to)) $to = OIDplusObject::parse($to);
493
                if (!($to instanceof $this)) return false;
494
                return oid_distance($to->oid, $this->oid);
495
        }
496
 
497
        public function getAltIds() {
498
                if ($this->isRoot()) return array();
499
                $ids = parent::getAltIds();
945 daniel-mar 500
 
635 daniel-mar 501
                if ($uuid = oid_to_uuid($this->oid)) {
929 daniel-mar 502
                        // UUID-OIDs are representation of an UUID
635 daniel-mar 503
                        $ids[] = new OIDplusAltId('guid', $uuid, _L('GUID representation of this OID'));
929 daniel-mar 504
                } else {
505
                        // All other OIDs can be formed into an UUID by making them a namebased OID
506
                        // You could theoretically also do this to an UUID-OID, but we exclude this case to avoid that users are confused
507
                        $ids[] = new OIDplusAltId('guid', gen_uuid_md5_namebased(UUID_NAMEBASED_NS_OID, $this->oid), _L('Name based version 3 / MD5 UUID with namespace %1','UUID_NAMEBASED_NS_OID'));
508
                        $ids[] = new OIDplusAltId('guid', gen_uuid_sha1_namebased(UUID_NAMEBASED_NS_OID, $this->oid), _L('Name based version 5 / SHA1 UUID with namespace %1','UUID_NAMEBASED_NS_OID'));
635 daniel-mar 509
                }
930 daniel-mar 510
 
945 daniel-mar 511
                // (VTS F0) IANA PEN to AID Mapping (PIX allowed)
512
                $oid_parts = explode('.',$this->nodeId(false));
513
                if ((count($oid_parts) == 7) && ($oid_parts[0] == '1') && ($oid_parts[1] == '3') && ($oid_parts[2] == '6') && ($oid_parts[3] == '1') && ($oid_parts[4] == '4') && ($oid_parts[5] == '1')) {
514
                        $pen = $oid_parts[6];
515
                        $aid = 'D276000186F0'.$pen;
516
                        if (strlen($aid)%2 == 1) $aid .= 'F';
517
                        $aid_is_ok = aid_canonize($aid);
959 daniel-mar 518
                        if ($aid_is_ok) $ids[] = new OIDplusAltId('aid', $aid, _L('Application Identifier (ISO/IEC 7816)'), ' ('._L('Optional PIX allowed, with "FF" prefix').')');
961 daniel-mar 519
                        $ids[] = new OIDplusAltId('iana-pen', $pen, _L('IANA Private Enterprise Number (PEN)'));
945 daniel-mar 520
                }
521
 
522
                // (VTS F1) FreeOID to AID Mapping (PIX allowed)
523
                $oid_parts = explode('.',$this->nodeId(false));
524
                if ((count($oid_parts) == 9) && ($oid_parts[0] == '1') && ($oid_parts[1] == '3') && ($oid_parts[2] == '6') && ($oid_parts[3] == '1') && ($oid_parts[4] == '4') && ($oid_parts[5] == '1') && ($oid_parts[6] == '37476') && ($oid_parts[7] == '9000')) {
525
                        $number = $oid_parts[8];
526
                        $aid = 'D276000186F1'.$number;
527
                        if (strlen($aid)%2 == 1) $aid .= 'F';
528
                        $aid_is_ok = aid_canonize($aid);
959 daniel-mar 529
                        if ($aid_is_ok) $ids[] = new OIDplusAltId('aid', $aid, _L('Application Identifier (ISO/IEC 7816)'), ' ('._L('Optional PIX allowed, with "FF" prefix').')');
945 daniel-mar 530
                }
531
 
532
                // (VTS F6) Mapping OID-to-AID if possible
933 daniel-mar 533
                try {
1050 daniel-mar 534
                        $test_der = \OidDerConverter::hexarrayToStr(\OidDerConverter::oidToDER($this->nodeId(false)));
535
                } catch (\Exception $e) {
933 daniel-mar 536
                        $test_der = '00'; // error, should not happen
537
                }
538
                if (substr($test_der,0,3) == '06 ') { // 06 = ASN.1 type of Absolute ID
539
                        $oid_parts = explode('.',$this->nodeId(false));
957 daniel-mar 540
                        if (($oid_parts[0] == '2') && ($oid_parts[1] == '999')) {
933 daniel-mar 541
                                // Note that "ViaThinkSoft E0" AID are not unique!
542
                                // OIDplus will use the relative DER of the 2.999.xx OID as PIX
543
                                $aid_candidate = 'D2 76 00 01 86 E0 ' . substr($test_der, strlen('06 xx 88 37 ')); // Remove ASN.1 06=Type, xx=Length and the 2.999 arcs "88 37"
945 daniel-mar 544
                                $aid_is_ok = aid_canonize($aid_candidate);
933 daniel-mar 545
                                if (!$aid_is_ok) {
546
                                        // If DER encoding is not possible (too long), then we will use a 32 bit small hash.
547
                                        $small_hash = str_pad(dechex(smallhash($this->nodeId(false))),8,'0',STR_PAD_LEFT);
548
                                        $aid_candidate = 'D2 76 00 01 86 E0 ' . strtoupper(implode(' ',str_split($small_hash,2)));
945 daniel-mar 549
                                        $aid_is_ok = aid_canonize($aid_candidate);
933 daniel-mar 550
                                }
959 daniel-mar 551
                                if ($aid_is_ok) $ids[] = new OIDplusAltId('aid', $aid_candidate, _L('Application Identifier (ISO/IEC 7816)'));
957 daniel-mar 552
                        } else if (($oid_parts[0] == '0') && ($oid_parts[1] == '4') && ($oid_parts[2] == '0') && ($oid_parts[3] == '127') && ($oid_parts[4] == '0') && ($oid_parts[5] == '7')) {
553
                                // Illegal usage of E8 by German BSI, plus using E8+Len+OID instead of E8+OID like ISO does
554
                                // PIX probably not used
555
                                $aid_candidate = 'E8 '.substr($test_der, strlen('06 ')); // Remove ASN.1 06=Type
556
                                $aid_is_ok = aid_canonize($aid_candidate);
959 daniel-mar 557
                                if ($aid_is_ok) $ids[] = new OIDplusAltId('aid', $aid_candidate, _L('Application Identifier (ISO/IEC 7816)'));
957 daniel-mar 558
                        } else if (($oid_parts[0] == '1') && ($oid_parts[1] == '0')) {
933 daniel-mar 559
                                // ISO Standard AID (OID 1.0.xx)
560
                                // Optional PIX allowed
561
                                $aid_candidate = 'E8 '.substr($test_der, strlen('06 xx ')); // Remove ASN.1 06=Type and xx=Length
945 daniel-mar 562
                                $aid_is_ok = aid_canonize($aid_candidate);
959 daniel-mar 563
                                if ($aid_is_ok) $ids[] = new OIDplusAltId('aid', $aid_candidate, _L('Application Identifier (ISO/IEC 7816)'), ' ('._L('Optional PIX allowed, without prefix').')');
930 daniel-mar 564
                        } else {
933 daniel-mar 565
                                // All other OIDs can be mapped using the "ViaThinkSoft F6" scheme, but only if the DER encoding is not too long
566
                                // No PIX allowed
567
                                $aid_candidate = 'D2 76 00 01 86 F6 '.substr($test_der, strlen('06 xx ')); // Remove ASN.1 06=Type and xx=Length
945 daniel-mar 568
                                $aid_is_ok = aid_canonize($aid_candidate);
959 daniel-mar 569
                                if ($aid_is_ok) $ids[] = new OIDplusAltId('aid', $aid_candidate, _L('Application Identifier (ISO/IEC 7816)'), ' ('._L('No PIX allowed').')');
930 daniel-mar 570
                        }
571
                }
572
 
635 daniel-mar 573
                return $ids;
574
        }
575
 
576
        public function getDirectoryName() {
577
                if ($this->isRoot()) return $this->ns();
578
                $oid = $this->nodeId(false);
579
                return $this->ns().'_'.str_replace('.', '_', $oid);
580
        }
800 daniel-mar 581
 
805 daniel-mar 582
        public static function treeIconFilename($mode) {
800 daniel-mar 583
                return 'img/'.$mode.'_icon16.png';
584
        }
635 daniel-mar 585
}