1 #!/usr/bin/env perl 1 #!/usr/bin/env perl 2 # SPDX-License-Identifier: GPL-2.0 2 # SPDX-License-Identifier: GPL-2.0 3 # 3 # 4 # extract-mod-sig <part> <module-file> 4 # extract-mod-sig <part> <module-file> 5 # 5 # 6 # Reads the module file and writes out some or 6 # Reads the module file and writes out some or all of the signature 7 # section to stdout. Part is the bit to be wr 7 # section to stdout. Part is the bit to be written and is one of: 8 # 8 # 9 # -0: The unsigned module, no signature data 9 # -0: The unsigned module, no signature data at all 10 # -a: All of the signature data, including ma 10 # -a: All of the signature data, including magic number 11 # -d: Just the descriptor values as a sequenc 11 # -d: Just the descriptor values as a sequence of numbers 12 # -n: Just the signer's name 12 # -n: Just the signer's name 13 # -k: Just the key ID 13 # -k: Just the key ID 14 # -s: Just the crypto signature or PKCS#7 mes 14 # -s: Just the crypto signature or PKCS#7 message 15 # 15 # 16 use warnings; 16 use warnings; 17 use strict; 17 use strict; 18 18 19 die "Format: $0 -[0adnks] module-file >out\n" 19 die "Format: $0 -[0adnks] module-file >out\n" 20 if ($#ARGV != 1); 20 if ($#ARGV != 1); 21 21 22 my $part = $ARGV[0]; 22 my $part = $ARGV[0]; 23 my $modfile = $ARGV[1]; 23 my $modfile = $ARGV[1]; 24 24 25 my $magic_number = "~Module signature appended 25 my $magic_number = "~Module signature appended~\n"; 26 26 27 # 27 # 28 # Read the module contents 28 # Read the module contents 29 # 29 # 30 open FD, "<$modfile" || die $modfile; 30 open FD, "<$modfile" || die $modfile; 31 binmode(FD); 31 binmode(FD); 32 my @st = stat(FD); 32 my @st = stat(FD); 33 die "$modfile" unless (@st); 33 die "$modfile" unless (@st); 34 my $buf = ""; 34 my $buf = ""; 35 my $len = sysread(FD, $buf, $st[7]); 35 my $len = sysread(FD, $buf, $st[7]); 36 die "$modfile" unless (defined($len)); 36 die "$modfile" unless (defined($len)); 37 die "Short read on $modfile\n" unless ($len == 37 die "Short read on $modfile\n" unless ($len == $st[7]); 38 close(FD) || die $modfile; 38 close(FD) || die $modfile; 39 39 40 print STDERR "Read ", $len, " bytes from modul 40 print STDERR "Read ", $len, " bytes from module file\n"; 41 41 42 die "The file is too short to have a sig magic 42 die "The file is too short to have a sig magic number and descriptor\n" 43 if ($len < 12 + length($magic_number)); 43 if ($len < 12 + length($magic_number)); 44 44 45 # 45 # 46 # Check for the magic number and extract the i 46 # Check for the magic number and extract the information block 47 # 47 # 48 my $p = $len - length($magic_number); 48 my $p = $len - length($magic_number); 49 my $raw_magic = substr($buf, $p); 49 my $raw_magic = substr($buf, $p); 50 50 51 die "Magic number not found at $len\n" 51 die "Magic number not found at $len\n" 52 if ($raw_magic ne $magic_number); 52 if ($raw_magic ne $magic_number); 53 print STDERR "Found magic number at $len\n"; 53 print STDERR "Found magic number at $len\n"; 54 54 55 $p -= 12; 55 $p -= 12; 56 my $raw_info = substr($buf, $p, 12); 56 my $raw_info = substr($buf, $p, 12); 57 57 58 my @info = unpack("CCCCCxxxN", $raw_info); 58 my @info = unpack("CCCCCxxxN", $raw_info); 59 my ($algo, $hash, $id_type, $name_len, $kid_le 59 my ($algo, $hash, $id_type, $name_len, $kid_len, $sig_len) = @info; 60 60 61 if ($id_type == 0) { 61 if ($id_type == 0) { 62 print STDERR "Found PGP key identifier\n"; 62 print STDERR "Found PGP key identifier\n"; 63 } elsif ($id_type == 1) { 63 } elsif ($id_type == 1) { 64 print STDERR "Found X.509 cert identifier\ 64 print STDERR "Found X.509 cert identifier\n"; 65 } elsif ($id_type == 2) { 65 } elsif ($id_type == 2) { 66 print STDERR "Found PKCS#7/CMS encapsulati 66 print STDERR "Found PKCS#7/CMS encapsulation\n"; 67 } else { 67 } else { 68 print STDERR "Found unsupported identifier 68 print STDERR "Found unsupported identifier type $id_type\n"; 69 } 69 } 70 70 71 # 71 # 72 # Extract the three pieces of info data 72 # Extract the three pieces of info data 73 # 73 # 74 die "Insufficient name+kid+sig data in file\n" 74 die "Insufficient name+kid+sig data in file\n" 75 unless ($p >= $name_len + $kid_len + $sig_ 75 unless ($p >= $name_len + $kid_len + $sig_len); 76 76 77 $p -= $sig_len; 77 $p -= $sig_len; 78 my $raw_sig = substr($buf, $p, $sig_len); 78 my $raw_sig = substr($buf, $p, $sig_len); 79 $p -= $kid_len; 79 $p -= $kid_len; 80 my $raw_kid = substr($buf, $p, $kid_len); 80 my $raw_kid = substr($buf, $p, $kid_len); 81 $p -= $name_len; 81 $p -= $name_len; 82 my $raw_name = substr($buf, $p, $name_len); 82 my $raw_name = substr($buf, $p, $name_len); 83 83 84 my $module_len = $p; 84 my $module_len = $p; 85 85 86 if ($sig_len > 0) { 86 if ($sig_len > 0) { 87 print STDERR "Found $sig_len bytes of sign 87 print STDERR "Found $sig_len bytes of signature ["; 88 my $n = $sig_len > 16 ? 16 : $sig_len; 88 my $n = $sig_len > 16 ? 16 : $sig_len; 89 foreach my $i (unpack("C" x $n, substr($ra 89 foreach my $i (unpack("C" x $n, substr($raw_sig, 0, $n))) { 90 printf STDERR "%02x", $i; 90 printf STDERR "%02x", $i; 91 } 91 } 92 print STDERR "]\n"; 92 print STDERR "]\n"; 93 } 93 } 94 94 95 if ($kid_len > 0) { 95 if ($kid_len > 0) { 96 print STDERR "Found $kid_len bytes of key 96 print STDERR "Found $kid_len bytes of key identifier ["; 97 my $n = $kid_len > 16 ? 16 : $kid_len; 97 my $n = $kid_len > 16 ? 16 : $kid_len; 98 foreach my $i (unpack("C" x $n, substr($ra 98 foreach my $i (unpack("C" x $n, substr($raw_kid, 0, $n))) { 99 printf STDERR "%02x", $i; 99 printf STDERR "%02x", $i; 100 } 100 } 101 print STDERR "]\n"; 101 print STDERR "]\n"; 102 } 102 } 103 103 104 if ($name_len > 0) { 104 if ($name_len > 0) { 105 print STDERR "Found $name_len bytes of sig 105 print STDERR "Found $name_len bytes of signer's name [$raw_name]\n"; 106 } 106 } 107 107 108 # 108 # 109 # Produce the requested output 109 # Produce the requested output 110 # 110 # 111 if ($part eq "-0") { 111 if ($part eq "-0") { 112 # The unsigned module, no signature data a 112 # The unsigned module, no signature data at all 113 binmode(STDOUT); 113 binmode(STDOUT); 114 print substr($buf, 0, $module_len); 114 print substr($buf, 0, $module_len); 115 } elsif ($part eq "-a") { 115 } elsif ($part eq "-a") { 116 # All of the signature data, including mag 116 # All of the signature data, including magic number 117 binmode(STDOUT); 117 binmode(STDOUT); 118 print substr($buf, $module_len); 118 print substr($buf, $module_len); 119 } elsif ($part eq "-d") { 119 } elsif ($part eq "-d") { 120 # Just the descriptor values as a sequence 120 # Just the descriptor values as a sequence of numbers 121 print join(" ", @info), "\n"; 121 print join(" ", @info), "\n"; 122 } elsif ($part eq "-n") { 122 } elsif ($part eq "-n") { 123 # Just the signer's name 123 # Just the signer's name 124 print STDERR "No signer's name for PKCS#7 124 print STDERR "No signer's name for PKCS#7 message type sig\n" 125 if ($id_type == 2); 125 if ($id_type == 2); 126 binmode(STDOUT); 126 binmode(STDOUT); 127 print $raw_name; 127 print $raw_name; 128 } elsif ($part eq "-k") { 128 } elsif ($part eq "-k") { 129 # Just the key identifier 129 # Just the key identifier 130 print STDERR "No key ID for PKCS#7 message 130 print STDERR "No key ID for PKCS#7 message type sig\n" 131 if ($id_type == 2); 131 if ($id_type == 2); 132 binmode(STDOUT); 132 binmode(STDOUT); 133 print $raw_kid; 133 print $raw_kid; 134 } elsif ($part eq "-s") { 134 } elsif ($part eq "-s") { 135 # Just the crypto signature or PKCS#7 mess 135 # Just the crypto signature or PKCS#7 message 136 binmode(STDOUT); 136 binmode(STDOUT); 137 print $raw_sig; 137 print $raw_sig; 138 } 138 }
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.