aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/x509keyid
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-10-25 15:20:36 -0400
committerTakashi Iwai <tiwai@suse.de>2012-10-25 15:20:36 -0400
commitc64064ce9376a404e0888ca4a2985c8a4c16cec3 (patch)
treef34d3b84ca970fdb381dad9a195c1367ce5d10f4 /scripts/x509keyid
parent21b3de881b38a84002c07b1b4bfb91892644e83f (diff)
parent456ba5a7802e58eccb5aa9751b3ab515ef99b9ca (diff)
Merge tag 'asoc-3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v3.7 A couple of driver fixes, one that improves the interoperability of WM8994 with controllers that are sensitive to extra BCLK cycles and some build break fixes for ux500.
Diffstat (limited to 'scripts/x509keyid')
-rwxr-xr-xscripts/x509keyid268
1 files changed, 0 insertions, 268 deletions
diff --git a/scripts/x509keyid b/scripts/x509keyid
deleted file mode 100755
index c8e91a4af385..000000000000
--- a/scripts/x509keyid
+++ /dev/null
@@ -1,268 +0,0 @@
1#!/usr/bin/perl -w
2#
3# Generate an identifier from an X.509 certificate that can be placed in a
4# module signature to indentify the key to use.
5#
6# Format:
7#
8# ./scripts/x509keyid <x509-cert> <signer's-name> <key-id>
9#
10# We read the DER-encoded X509 certificate and parse it to extract the Subject
11# name and Subject Key Identifier. The provide the data we need to build the
12# certificate identifier.
13#
14# The signer's name part of the identifier is fabricated from the commonName,
15# the organizationName or the emailAddress components of the X.509 subject
16# name and written to the second named file.
17#
18# The subject key ID to select which of that signer's certificates we're
19# intending to use to sign the module is written to the third named file.
20#
21use strict;
22
23my $raw_data;
24
25die "Need three filenames\n" if ($#ARGV != 2);
26
27my $src = $ARGV[0];
28
29open(FD, "<$src") || die $src;
30binmode FD;
31my @st = stat(FD);
32die $src if (!@st);
33read(FD, $raw_data, $st[7]) || die $src;
34close(FD);
35
36my $UNIV = 0 << 6;
37my $APPL = 1 << 6;
38my $CONT = 2 << 6;
39my $PRIV = 3 << 6;
40
41my $CONS = 0x20;
42
43my $BOOLEAN = 0x01;
44my $INTEGER = 0x02;
45my $BIT_STRING = 0x03;
46my $OCTET_STRING = 0x04;
47my $NULL = 0x05;
48my $OBJ_ID = 0x06;
49my $UTF8String = 0x0c;
50my $SEQUENCE = 0x10;
51my $SET = 0x11;
52my $UTCTime = 0x17;
53my $GeneralizedTime = 0x18;
54
55my %OIDs = (
56 pack("CCC", 85, 4, 3) => "commonName",
57 pack("CCC", 85, 4, 6) => "countryName",
58 pack("CCC", 85, 4, 10) => "organizationName",
59 pack("CCC", 85, 4, 11) => "organizationUnitName",
60 pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 1) => "rsaEncryption",
61 pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 5) => "sha1WithRSAEncryption",
62 pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 9, 1) => "emailAddress",
63 pack("CCC", 85, 29, 35) => "authorityKeyIdentifier",
64 pack("CCC", 85, 29, 14) => "subjectKeyIdentifier",
65 pack("CCC", 85, 29, 19) => "basicConstraints"
66);
67
68###############################################################################
69#
70# Extract an ASN.1 element from a string and return information about it.
71#
72###############################################################################
73sub asn1_extract($$@)
74{
75 my ($cursor, $expected_tag, $optional) = @_;
76
77 return [ -1 ]
78 if ($cursor->[1] == 0 && $optional);
79
80 die $src, ": ", $cursor->[0], ": ASN.1 data underrun (elem ", $cursor->[1], ")\n"
81 if ($cursor->[1] < 2);
82
83 my ($tag, $len) = unpack("CC", substr(${$cursor->[2]}, $cursor->[0], 2));
84
85 if ($expected_tag != -1 && $tag != $expected_tag) {
86 return [ -1 ]
87 if ($optional);
88 die $src, ": ", $cursor->[0], ": ASN.1 unexpected tag (", $tag,
89 " not ", $expected_tag, ")\n";
90 }
91
92 $cursor->[0] += 2;
93 $cursor->[1] -= 2;
94
95 die $src, ": ", $cursor->[0], ": ASN.1 long tag\n"
96 if (($tag & 0x1f) == 0x1f);
97 die $src, ": ", $cursor->[0], ": ASN.1 indefinite length\n"
98 if ($len == 0x80);
99
100 if ($len > 0x80) {
101 my $l = $len - 0x80;
102 die $src, ": ", $cursor->[0], ": ASN.1 data underrun (len len $l)\n"
103 if ($cursor->[1] < $l);
104
105 if ($l == 0x1) {
106 $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1));
107 } elsif ($l = 0x2) {
108 $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2));
109 } elsif ($l = 0x3) {
110 $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16;
111 $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2));
112 } elsif ($l = 0x4) {
113 $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4));
114 } else {
115 die $src, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n";
116 }
117
118 $cursor->[0] += $l;
119 $cursor->[1] -= $l;
120 }
121
122 die $src, ": ", $cursor->[0], ": ASN.1 data underrun (", $len, ")\n"
123 if ($cursor->[1] < $len);
124
125 my $ret = [ $tag, [ $cursor->[0], $len, $cursor->[2] ] ];
126 $cursor->[0] += $len;
127 $cursor->[1] -= $len;
128
129 return $ret;
130}
131
132###############################################################################
133#
134# Retrieve the data referred to by a cursor
135#
136###############################################################################
137sub asn1_retrieve($)
138{
139 my ($cursor) = @_;
140 my ($offset, $len, $data) = @$cursor;
141 return substr($$data, $offset, $len);
142}
143
144###############################################################################
145#
146# Roughly parse the X.509 certificate
147#
148###############################################################################
149my $cursor = [ 0, length($raw_data), \$raw_data ];
150
151my $cert = asn1_extract($cursor, $UNIV | $CONS | $SEQUENCE);
152my $tbs = asn1_extract($cert->[1], $UNIV | $CONS | $SEQUENCE);
153my $version = asn1_extract($tbs->[1], $CONT | $CONS | 0, 1);
154my $serial_number = asn1_extract($tbs->[1], $UNIV | $INTEGER);
155my $sig_type = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
156my $issuer = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
157my $validity = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
158my $subject = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
159my $key = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
160my $issuer_uid = asn1_extract($tbs->[1], $CONT | $CONS | 1, 1);
161my $subject_uid = asn1_extract($tbs->[1], $CONT | $CONS | 2, 1);
162my $extension_list = asn1_extract($tbs->[1], $CONT | $CONS | 3, 1);
163
164my $subject_key_id = ();
165my $authority_key_id = ();
166
167#
168# Parse the extension list
169#
170if ($extension_list->[0] != -1) {
171 my $extensions = asn1_extract($extension_list->[1], $UNIV | $CONS | $SEQUENCE);
172
173 while ($extensions->[1]->[1] > 0) {
174 my $ext = asn1_extract($extensions->[1], $UNIV | $CONS | $SEQUENCE);
175 my $x_oid = asn1_extract($ext->[1], $UNIV | $OBJ_ID);
176 my $x_crit = asn1_extract($ext->[1], $UNIV | $BOOLEAN, 1);
177 my $x_val = asn1_extract($ext->[1], $UNIV | $OCTET_STRING);
178
179 my $raw_oid = asn1_retrieve($x_oid->[1]);
180 next if (!exists($OIDs{$raw_oid}));
181 my $x_type = $OIDs{$raw_oid};
182
183 my $raw_value = asn1_retrieve($x_val->[1]);
184
185 if ($x_type eq "subjectKeyIdentifier") {
186 my $vcursor = [ 0, length($raw_value), \$raw_value ];
187
188 $subject_key_id = asn1_extract($vcursor, $UNIV | $OCTET_STRING);
189 }
190 }
191}
192
193###############################################################################
194#
195# Determine what we're going to use as the signer's name. In order of
196# preference, take one of: commonName, organizationName or emailAddress.
197#
198###############################################################################
199my $org = "";
200my $cn = "";
201my $email = "";
202
203while ($subject->[1]->[1] > 0) {
204 my $rdn = asn1_extract($subject->[1], $UNIV | $CONS | $SET);
205 my $attr = asn1_extract($rdn->[1], $UNIV | $CONS | $SEQUENCE);
206 my $n_oid = asn1_extract($attr->[1], $UNIV | $OBJ_ID);
207 my $n_val = asn1_extract($attr->[1], -1);
208
209 my $raw_oid = asn1_retrieve($n_oid->[1]);
210 next if (!exists($OIDs{$raw_oid}));
211 my $n_type = $OIDs{$raw_oid};
212
213 my $raw_value = asn1_retrieve($n_val->[1]);
214
215 if ($n_type eq "organizationName") {
216 $org = $raw_value;
217 } elsif ($n_type eq "commonName") {
218 $cn = $raw_value;
219 } elsif ($n_type eq "emailAddress") {
220 $email = $raw_value;
221 }
222}
223
224my $id_name = $email;
225
226if ($org && $cn) {
227 # Don't use the organizationName if the commonName repeats it
228 if (length($org) <= length($cn) &&
229 substr($cn, 0, length($org)) eq $org) {
230 $id_name = $cn;
231 goto got_id_name;
232 }
233
234 # Or a signifcant chunk of it
235 if (length($org) >= 7 &&
236 length($cn) >= 7 &&
237 substr($cn, 0, 7) eq substr($org, 0, 7)) {
238 $id_name = $cn;
239 goto got_id_name;
240 }
241
242 $id_name = $org . ": " . $cn;
243} elsif ($org) {
244 $id_name = $org;
245} elsif ($cn) {
246 $id_name = $cn;
247}
248
249got_id_name:
250
251###############################################################################
252#
253# Output the signer's name and the key identifier that we're going to include
254# in module signatures.
255#
256###############################################################################
257die $src, ": ", "X.509: Couldn't find the Subject Key Identifier extension\n"
258 if (!$subject_key_id);
259
260my $id_key_id = asn1_retrieve($subject_key_id->[1]);
261
262open(OUTFD, ">$ARGV[1]") || die $ARGV[1];
263print OUTFD $id_name;
264close OUTFD || die $ARGV[1];
265
266open(OUTFD, ">$ARGV[2]") || die $ARGV[2];
267print OUTFD $id_key_id;
268close OUTFD || die $ARGV[2];