Subversion Repositories php_utils

Rev

Rev 44 | Rev 46 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 44 Rev 45
Line 22... Line 22...
22
include_once __DIR__ . '/misc_functions.inc.php';
22
include_once __DIR__ . '/misc_functions.inc.php';
23
 
23
 
24
# ---
24
# ---
25
 
25
 
26
/*
26
/*
27
#test2('A000000051AABBCC');
27
#test2('A000000051AABBCC'); // International Registration
28
#test2('B01234567890');
28
#test2('B01234567890'); // Illegal AID (RFU)
29
#test2('D276000098AABBCCDDEEFFAABBCCDDEE');
29
#test2('D276000098AABBCCDDEEFFAABBCCDDEE'); // National Registration
30
#test2('F01234567890');
30
#test2('F01234567890'); // Unregistered AID
31
#test('91234FFF999');
31
#test('91234FFF999'); // IIN based AID
32
#test('51234FFF999');
32
#test('51234FFF999'); // IIN based AID
33
#test2('E828BD080F014E585031');
33
test('E828BD080F014E585031'); // ISO E8-OID 1.0.aaaa
-
 
34
test('E80704007F00070304'); // BSI Illegal E8-OID-AID (with DER Length)
-
 
35
test('E80704007F0007030499'); // BSI Illegal E8-OID-AID + PIX (PIX is never used by BSI; it's just for us to test)
34
 
36
 
35
function test2($aid) {
37
function test2($aid) {
36
        while ($aid != '') {
38
        while ($aid != '') {
37
                echo test($aid);
39
                echo test($aid);
38
                $aid = substr($aid,0,strlen($aid)-1);
40
                $aid = substr($aid,0,strlen($aid)-1);
Line 58... Line 60...
58
}
60
}
59
*/
61
*/
60
 
62
 
61
# ---
63
# ---
62
 
64
 
-
 
65
function _aid_e8_oid_helper($output_oid,$by,$ii,&$ret,$minmax_measure,$min,$max) {
-
 
66
        if ($minmax_measure == 'ARC') {
-
 
67
                if (($min!=-1) && (count($output_oid)<$min)) return true;  // continue
-
 
68
                if (($max!=-1) && (count($output_oid)>$max)) return false; // stop
-
 
69
        } else if ($minmax_measure == 'DER') {
-
 
70
                if (($min!=-1) && ($ii+1<$min)) return true;  // continue
-
 
71
                if (($max!=-1) && ($ii+1>$max)) return false; // stop
-
 
72
        }
-
 
73
 
-
 
74
        $byy = $by;
-
 
75
        for ($i=0;$i<=$ii;$i++) array_shift($byy);
-
 
76
 
-
 
77
        $is_iso_standard = (count($output_oid) >= 3) && ($output_oid[0] == '1') && ($output_oid[1] == '0');
-
 
78
 
-
 
79
        $s_oid = implode('.',$output_oid);
-
 
80
 
-
 
81
        if ($is_iso_standard) {
-
 
82
                $std_hf = 'Standard ISO/IEC '.$output_oid[2];
-
 
83
                if (isset($output_oid[3])) $std_hf .= "-".$output_oid[3];
-
 
84
        } else {
-
 
85
                $std_hf = "Unknown Standard"; // should not happen
-
 
86
        }
-
 
87
 
-
 
88
        $pix = implode(':',$byy);
-
 
89
 
-
 
90
        if ($pix !== '') {
-
 
91
                $ret[] = array($ii+1,"$std_hf (OID $s_oid)",$pix);
-
 
92
        } else {
-
 
93
                $ret[] = array($ii+1,"$std_hf (OID $s_oid)","");
-
 
94
        }
-
 
95
 
-
 
96
        return true;
-
 
97
}
-
 
98
 
63
function _aid_e8_interpretations($aid) {
99
function _aid_e8_interpretations($pure_der, $minmax_measure='ARC', $min=-1, $max=-1) {
64
        $ret = array();
100
        $ret = array();
65
 
101
 
66
        $output_oid = array();
102
        $output_oid = array();
67
 
103
 
68
        $aid = strtoupper(str_replace(' ','',$aid));
104
        $pure_der = strtoupper(str_replace(' ','',$pure_der));
69
        $aid = strtoupper(str_replace(':','',$aid));
105
        $pure_der = strtoupper(str_replace(':','',$pure_der));
70
        $by = str_split($aid,2);
106
        $by = str_split($pure_der,2);
71
        if ((array_shift($by) == 'E8') ) {
-
 
-
 
107
 
72
                // The following part is partially taken from the DER decoder/encoder by Daniel Marschall:
108
        // The following part is partially taken from the DER decoder/encoder by Daniel Marschall:
73
                // https://github.com/danielmarschall/oidconverter/blob/master/php/OidDerConverter.class.phps
109
        // https://github.com/danielmarschall/oidconverter/blob/master/php/OidDerConverter.class.phps
74
                // (Only the DER "value" part, without "type" and "length")
110
        // (Only the DER "value" part, without "type" and "length")
75
 
111
 
76
                $part = 2; // DER part 0 (type) and part 1 (length) not present
112
        $part = 2; // DER part 0 (type) and part 1 (length) not present
Line 86... Line 122...
86
                                $first = floor($pb / 40);
122
                        $first = floor($pb / 40);
87
                                $second = $pb % 40;
123
                        $second = $pb % 40;
88
                                if ($first > 2) {
124
                        if ($first > 2) {
89
                                        $first = 2;
125
                                $first = 2;
90
                                        $output_oid[] = $first;
126
                                $output_oid[] = $first;
-
 
127
                                if (!_aid_e8_oid_helper($output_oid, $by, $ii, $ret, $minmax_measure, $min, $max)) break;
91
                                        $arcBeginning = true;
128
                                $arcBeginning = true;
92
 
129
 
93
                                        if (($pb & 0x80) != 0) {
130
                                if (($pb & 0x80) != 0) {
94
                                                // 2.48 and up => 2+ octets
131
                                        // 2.48 and up => 2+ octets
95
                                                // Output in "part 3"
132
                                        // Output in "part 3"
Line 105... Line 142...
105
                                                $fOK = false;
142
                                        $fOK = false;
106
                                        } else {
143
                                } else {
107
                                                // 2.0 till 2.47 => 1 octet
144
                                        // 2.0 till 2.47 => 1 octet
108
                                                $second = $pb - 80;
145
                                        $second = $pb - 80;
109
                                                $output_oid[] = $second;
146
                                        $output_oid[] = $second;
-
 
147
                                        if (!_aid_e8_oid_helper($output_oid, $by, $ii, $ret, $minmax_measure, $min, $max)) break;
110
                                                $arcBeginning = true;
148
                                        $arcBeginning = true;
111
                                                $fOK = true;
149
                                        $fOK = true;
112
                                                $ll = gmp_init(0);
150
                                        $ll = gmp_init(0);
113
                                        }
151
                                }
114
                                } else {
152
                        } else {
115
                                        // 0.0 till 0.37 => 1 octet
153
                                // 0.0 till 0.37 => 1 octet
116
                                        // 1.0 till 1.37 => 1 octet
154
                                // 1.0 till 1.37 => 1 octet
117
                                        $output_oid[] = $first;
155
                                $output_oid[] = $first;
118
                                        $output_oid[] = $second;
156
                                $output_oid[] = $second;
-
 
157
                                if (!_aid_e8_oid_helper($output_oid, $by, $ii, $ret, $minmax_measure, $min, $max)) break;
119
                                        $arcBeginning = true;
158
                                $arcBeginning = true;
120
                                        $fOK = true;
159
                                $fOK = true;
121
                                        $ll = gmp_init(0);
160
                                $ll = gmp_init(0);
122
                                }
161
                        }
123
                                $part++;
162
                        $part++;
Line 137... Line 176...
137
                                        $ll = gmp_mul($ll, 0x80);
176
                                $ll = gmp_mul($ll, 0x80);
138
                                        $ll = gmp_add($ll, $pb);
177
                                $ll = gmp_add($ll, $pb);
139
                                        $ll = gmp_sub($ll, $fSub);
178
                                $ll = gmp_sub($ll, $fSub);
140
                                        $output_oid[] = gmp_strval($ll, 10);
179
                                $output_oid[] = gmp_strval($ll, 10);
141
 
180
 
142
                                        $is_iso_standard = ($output_oid[0] == '1') && ($output_oid[1] == '0');
181
                                if (!_aid_e8_oid_helper($output_oid, $by, $ii, $ret, $minmax_measure, $min, $max)) break;
143
 
-
 
144
                                        $byy = $by;
-
 
145
                                        for ($i=0;$i<=$ii;$i++) array_shift($byy);
-
 
146
 
-
 
147
                                        $s_oid = implode('.',$output_oid);
-
 
148
 
-
 
149
                                        if ($is_iso_standard) {
-
 
150
                                                $std_hf = 'Standard ISO/IEC '.$output_oid[2];
-
 
151
                                                if (isset($output_oid[3])) $std_hf .= "-".$output_oid[3];
-
 
152
                                        } else {
-
 
153
                                                $std_hf = "Unknown Standard"; // should not happen
-
 
154
                                        }
-
 
155
 
-
 
156
                                        $pix = implode(':',$byy);
-
 
157
 
-
 
158
                                        if ($pix !== '') {
-
 
159
                                                $ret[] = array($ii+1,"$std_hf (OID $s_oid)",$pix);
-
 
160
                                        } else {
-
 
161
                                                $ret[] = array($ii+1,"$std_hf (OID $s_oid)","");
-
 
162
                                        }
-
 
163
 
-
 
164
                                        // ISO Standards (OID 1.0) will only have 1 or 2 numbers. (Number 1 is the standard, and number 2
-
 
165
                                        // is the part in case of a multi-part standard).
-
 
166
                                        if ($is_iso_standard && (count($output_oid) == 4)) break;
-
 
167
 
182
 
168
                                        // Happens only if 0x80 paddings are allowed
183
                                // Happens only if 0x80 paddings are allowed
169
                                        // $fOK = gmp_cmp($ll, 0) >= 0;
184
                                // $fOK = gmp_cmp($ll, 0) >= 0;
170
                                        $ll = gmp_init(0);
185
                                $ll = gmp_init(0);
171
                                        $fSub = 0;
186
                                $fSub = 0;
172
                                        $arcBeginning = true;
187
                                $arcBeginning = true;
173
                                }
188
                        }
174
                        }
189
                }
175
                }
190
        }
176
        }
191
 
177
        return $ret;
192
        return $ret;
178
}
193
}
179
 
194
 
180
function decode_aid($aid,$compact=true) {
195
function decode_aid($aid,$compact=true) {
181
        $sout = '';
196
        $sout = '';
-
 
197
        if (strtolower(substr($aid,0,2)) == '0x') $aid = substr($aid,2);
182
        $out = _decode_aid($aid);
198
        $out = _decode_aid($aid);
183
        if ($compact) {
199
        if ($compact) {
184
                $max_key_len = 0;
200
                $max_key_len = 0;
185
                foreach ($out as $a) {
201
                foreach ($out as $a) {
186
                        if (is_array($a)) {
202
                        if (is_array($a)) {
Line 205... Line 221...
205
}
221
}
206
 
222
 
207
function _decode_aid($aid) {
223
function _decode_aid($aid) {
208
 
224
 
209
        // based on https://github.com/thephpleague/iso3166/blob/main/src/ISO3166.php
225
        // based on https://github.com/thephpleague/iso3166/blob/main/src/ISO3166.php
210
        // commit 26.07.2022
226
        // commit 26 July 2022
211
        // Generated using:
227
        // Generated using:
212
        /*
228
        /*
213
        $x = new ISO3166();
229
        $x = new ISO3166();
214
        $bla = $x->all();
230
        $bla = $x->all();
215
        foreach ($bla as $data) {
231
        foreach ($bla as $data) {
Line 690... Line 706...
690
 
706
 
691
                $std_schema = substr($aid,1,1);
707
                $std_schema = substr($aid,1,1);
692
                if ($std_schema == '8') {
708
                if ($std_schema == '8') {
693
                        $out[] = array(" $std_schema", "Standard identified by OID");
709
                        $out[] = array(" $std_schema", "Standard identified by OID");
694
 
710
 
-
 
711
                        // Including the DER Encoding "Length" is not defined by ISO but used illegally
-
 
712
                        // by German BSI (beside the fact that ISO never allowed anyone else to use E8-AIDs outside
-
 
713
                        // of OID arc 1.0),
-
 
714
                        // e.g. 0xE80704007F00070302 defined by "BSI TR-03110" was intended to represent 0.4.0.127.0.7.3.2
-
 
715
                        //                           "more correct" would have been 0xE804007F00070302
-
 
716
                        //      0xE80704007F00070304 defined by "BSI TR-03109-2" was intended to represent 0.4.0.127.0.7.3.4
-
 
717
                        //                           "more correct" would have been 0xE804007F00070304
-
 
718
                        $include_der_length_roots = array(
-
 
719
                                '04007F0007' /* bsi-de (0.4.0.127.0.7) */
-
 
720
                        );
-
 
721
                        $include_der_length = false;
-
 
722
                        foreach ($include_der_length_roots as $include_der_length_root) {
-
 
723
                                $der_length_hex = null;
-
 
724
                                $der_length_dec = null;
-
 
725
                                if (substr($aid,4,strlen($include_der_length_root)) == $include_der_length_root) {
-
 
726
                                        $der_length_hex = substr($aid,2,2);
-
 
727
                                        $der_length_dec = hexdec($der_length_hex);
-
 
728
                                        if ($der_length_dec <= 14) {
-
 
729
                                                $include_der_length = true;
-
 
730
                                                break;
-
 
731
                                        }
-
 
732
                                }
-
 
733
                        }
-
 
734
                        if ($include_der_length) {
-
 
735
                                $out[] = array("  $der_length_hex", "DER encoding length (illegal usage not defined by ISO)");
-
 
736
                                $pure_der = substr($aid,4);
-
 
737
                                $indent = 4;
-
 
738
                                $e8_minmax_measure = 'DER';
-
 
739
                                $e8_min = $der_length_dec;
-
 
740
                                $e8_max = $der_length_dec;
-
 
741
                        } else {
695
                        $data = substr($aid,2);
742
                                $pure_der = substr($aid,2);
-
 
743
                                $indent = 2;
-
 
744
                                // ISO Standards (OID 1.0) will only have 1 or 2 numbers. (Number 1 is the standard, and number 2
-
 
745
                                // is the part in case of a multi-part standard).
-
 
746
                                $e8_minmax_measure = 'ARC';
-
 
747
                                $e8_min = 3; // 1.0.aaaa   (ISO AAAA)
-
 
748
                                $e8_max = 4; // 1.0.aaaa.b (ISO AAAA-B)
-
 
749
                        }
-
 
750
                        // --- End of BSI compatibility hack ---
-
 
751
 
696
                        try {
752
                        try {
697
                                $interpretations = _aid_e8_interpretations($aid);
753
                                $interpretations = _aid_e8_interpretations($pure_der,$e8_minmax_measure,$e8_min,$e8_max);
698
                                foreach ($interpretations as $ii => $interpretation) {
754
                                foreach ($interpretations as $ii => $interpretation) {
699
                                        $pos = $interpretation[0];
755
                                        $pos = $interpretation[0];
700
                                        $txt1 = $interpretation[1]; // Standard
756
                                        $txt1 = $interpretation[1]; // Standard
701
                                        $txt2 = $interpretation[2]; // PIX (optional)
757
                                        $txt2 = $interpretation[2]; // PIX (optional)
702
 
758
 
703
                                        $aid1 = '  '.substr($aid,2,$pos*2);
759
                                        $aid1 = str_repeat(' ',$indent).substr($pure_der,0,$pos*2);
704
                                        $aid2 = substr($aid,2+$pos*2);
760
                                        $aid2 = substr($pure_der,$pos*2);
705
 
761
 
706
                                        $out[] = array("$aid1", "$txt1");
762
                                        $out[] = array("$aid1", "$txt1");
707
                                        if ($txt2 !== '') {
763
                                        if ($txt2 !== '') {
708
                                                $pix = "$txt2 (".c_literal_hexstr(str_replace(':','',$txt2)).")";
764
                                                $pix = "$txt2 (".c_literal_hexstr(str_replace(':','',$txt2)).")";
709
                                                $out[] = array(str_repeat(' ',strlen($aid1))."$aid2", "with PIX $pix");
765
                                                $out[] = array(str_repeat(' ',strlen($aid1))."$aid2", "with PIX $pix");
Line 711... Line 767...
711
                                        if ($ii < count($interpretations)-1) {
767
                                        if ($ii < count($interpretations)-1) {
712
                                                $out[] = array('', 'or:');
768
                                                $out[] = array('', 'or:');
713
                                        }
769
                                        }
714
                                }
770
                                }
715
                        } catch (Exception $e) {
771
                        } catch (Exception $e) {
716
                                $out[] = array("  $data", "ERROR: ".$e->getMessage());
772
                                $out[] = array(str_repeat(' ',$indent).$pure_der, "ERROR: ".$e->getMessage());
717
 
-
 
718
                        }
773
                        }
719
                } else if ($std_schema != '') {
774
                } else if ($std_schema != '') {
720
                        // E0..E7, E9..EF are RFU
775
                        // E0..E7, E9..EF are RFU
721
                        $unknown = substr($aid,1);
776
                        $unknown = substr($aid,1);
722
                        $out[] = array(" $unknown", "ILLEGAL USAGE / RESERVED");
777
                        $out[] = array(" $unknown", "ILLEGAL USAGE / RESERVED");