Skip to content

Commit

Permalink
[backend] BSASN1.pm: get rid of asn1_ prefixes
Browse files Browse the repository at this point in the history
It makes no sense to have them if the module is called BSASN1...
  • Loading branch information
mlschroe authored and coolo committed Nov 14, 2018
1 parent 6b920c3 commit 56cbb1e
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 124 deletions.
140 changes: 70 additions & 70 deletions src/backend/BSASN1.pm
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ sub pem2der {
}

# raw packing/unpacking helpers
sub asn1_pack {
sub pack_raw {
my ($tag, @data) = @_;
my $data = join('', @data);
my $l = length($data);
Expand All @@ -90,7 +90,7 @@ sub asn1_pack {
return pack("CCa*", $tag, $ll | 0x80, substr(pack("N", $l), -$ll)) . $data;
}

sub asn1_unpack {
sub unpack_raw {
my ($in, $allowed, $optional, $exact) = @_;
$allowed = [ $allowed ] if $allowed && !ref($allowed);
if (length($in) < 2) {
Expand All @@ -117,156 +117,156 @@ sub asn1_unpack {
}

# little pack helpers
sub asn1_null {
return asn1_pack($NULL);
sub pack_null {
return pack_raw($NULL);
}

sub asn1_boolean {
return asn1_pack($BOOLEAN, pack('C', $_[0] ? 255 : 0));
sub pack_boolean {
return pack_raw($BOOLEAN, pack('C', $_[0] ? 255 : 0));
}

sub asn1_integer {
return asn1_pack($INTEGER, pack('c', $_[0])) if $_[0] >= -128 && $_[0] <= 127;
return asn1_pack($INTEGER, substr(pack('N', $_[0]), 3 - (length(sprintf('%b', $_[0] >= 0 ? $_[0] : ~$_[0])) >> 3)));
sub pack_integer {
return pack_raw($INTEGER, pack('c', $_[0])) if $_[0] >= -128 && $_[0] <= 127;
return pack_raw($INTEGER, substr(pack('N', $_[0]), 3 - (length(sprintf('%b', $_[0] >= 0 ? $_[0] : ~$_[0])) >> 3)));
}

sub asn1_integer_mpi {
sub pack_integer_mpi {
my $mpi = $_[0];
$mpi = pack('C', 0) if length($mpi) == 0;
$mpi = substr($mpi, 1) while length($mpi) > 1 && unpack('C', $mpi) == 0;
return asn1_pack($INTEGER, unpack('C', $mpi) >= 128 ? pack('C', 0).$mpi : $mpi);
return pack_raw($INTEGER, unpack('C', $mpi) >= 128 ? pack('C', 0).$mpi : $mpi);
}

sub asn1_enumerated {
return asn1_pack($ENUMERATED, pack('c', $_[0])) if $_[0] >= -128 && $_[0] <= 127;
return asn1_pack($ENUMERATED, substr(pack('N', $_[0]), 3 - (length(sprintf('%b', $_[0] >= 0 ? $_[0] : ~$_[0])) >> 3)));
sub pack_enumerated {
return pack_raw($ENUMERATED, pack('c', $_[0])) if $_[0] >= -128 && $_[0] <= 127;
return pack_raw($ENUMERATED, substr(pack('N', $_[0]), 3 - (length(sprintf('%b', $_[0] >= 0 ? $_[0] : ~$_[0])) >> 3)));
}

sub asn1_obj_id {
sub pack_obj_id {
my ($o1, $o2, @o) = @_;
return asn1_pack($OBJ_ID, pack('w*', $o1 * 40 + $o2, @o));
return pack_raw($OBJ_ID, pack('w*', $o1 * 40 + $o2, @o));
}

sub asn1_sequence {
return asn1_pack($CONS | $SEQUENCE, @_);
sub pack_sequence {
return pack_raw($CONS | $SEQUENCE, @_);
}

sub asn1_set {
return asn1_pack($CONS | $SET, @_);
sub pack_set {
return pack_raw($CONS | $SET, @_);
}

sub asn1_utctime {
return asn1_pack($UTCTIME, utctime(@_));
sub pack_utctime {
return pack_raw($UTCTIME, utctime(@_));
}

sub asn1_gentime {
return asn1_pack($GENTIME, gentime(@_));
sub pack_gentime {
return pack_raw($GENTIME, gentime(@_));
}

sub asn1_octet_string {
return asn1_pack($OCTET_STRING, $_[0]);
sub pack_octet_string {
return pack_raw($OCTET_STRING, $_[0]);
}

sub asn1_string {
sub pack_string {
my ($s, $tag) = @_;
Encode::_utf8_off($s); # hope for the best
return asn1_pack($tag || $UTF8STRING, $s);
return pack_raw($tag || $UTF8STRING, $s);
}

sub asn1_bytes {
return asn1_pack($BIT_STRING, pack('C', 0).$_[0]);
sub pack_bytes {
return pack_raw($BIT_STRING, pack('C', 0).$_[0]);
}

sub asn1_tagged {
return asn1_pack(($_[0] < 0x40 ? $CONT : 0) | $CONS | $_[0], $_[1]);
sub pack_tagged {
return pack_raw(($_[0] < 0x40 ? $CONT : 0) | $CONS | $_[0], $_[1]);
}

sub asn1_tagged_implicit {
my ($rest, $tag, $body) = asn1_unpack($_[1]);
return asn1_pack(($_[0] < 0x40 ? $CONT : 0) | ($tag & $CONS) | $_[0], $body).$rest;
sub pack_tagged_implicit {
my ($rest, $tag, $body) = unpack_raw($_[1]);
return pack_raw(($_[0] < 0x40 ? $CONT : 0) | ($tag & $CONS) | $_[0], $body).$rest;
}

sub asn1_bits_list {
sub pack_bits_list {
my $v = '';
vec($v, $_ ^ 7, 1) = 1 for @_;
my $maxbit = $v eq '' ? 7 : (sort {$b <=> $a} @_)[0];
return asn1_pack($BIT_STRING, pack('C', 7 - ($maxbit % 8)).$v);
return pack_raw($BIT_STRING, pack('C', 7 - ($maxbit % 8)).$v);
}


# little unpack helpers (intag = 0 : any tag allowed)
# little unpack helpers (tag = 0 : any tag allowed)

sub asn1_gettag {
return (asn1_unpack(@_))[1];
sub gettag {
return (unpack_raw(@_))[1];
}

sub asn1_unpack_body {
my ($in, $intag, $default) = @_;
return (asn1_unpack($in, defined($intag) ? $intag : $default, undef, 1))[2];
sub unpack_body {
my ($in, $tag, $default) = @_;
return (unpack_raw($in, defined($tag) ? $tag : $default, undef, 1))[2];
}

sub asn1_unpack_integer {
my $in = asn1_unpack_body($_[0], $_[1], $INTEGER);
sub unpack_integer {
my $in = unpack_body($_[0], $_[1], $INTEGER);
return 0 if $in eq '';
return unpack('c', $in) if length($in) == 1;
my $n = pack('C', unpack('C', $in) >= 128 ? 255 : 0) x 4;
$n = unpack('N', substr("$n$in", -4));
return unpack('C', $in) >= 128 ? $n - 4294967296 : $n;
}

sub asn1_unpack_integer_mpi {
my $in = asn1_unpack_body($_[0], $_[1], $INTEGER);
sub unpack_integer_mpi {
my $in = unpack_body($_[0], $_[1], $INTEGER);
$in = substr($in, 1) while $in ne '' && unpack('C', $in) == 0;
return $in;
}

sub asn1_unpack_sequence {
my ($in, $intag, $allowed) = @_;
$in = asn1_unpack_body($in, $intag, $CONS | $SEQUENCE);
sub unpack_sequence {
my ($in, $tag, $allowed) = @_;
$in = unpack_body($in, $tag, $CONS | $SEQUENCE);
my @ret;
my $tagbody;
if ($allowed && ref($allowed)) {
for my $all (@$allowed) {
return @ret, $in if $all && !ref($all) && $all == -1; # -1: get rest
($in, undef, undef, $tagbody) = asn1_unpack($in, $all);
($in, undef, undef, $tagbody) = unpack_raw($in, $all);
push @ret, $tagbody;
}
die("tailing data at end of asn1 sequence\n") if $in ne '';
return @ret;
}
while ($in ne '') {
($in, undef, undef, $tagbody) = asn1_unpack($in, $allowed);
($in, undef, undef, $tagbody) = unpack_raw($in, $allowed);
push @ret, $tagbody;
}
return @ret;
}

sub asn1_unpack_set {
my ($in, $intag, $allowed) = @_;
my $in = asn1_unpack_body($in, $intag, $CONS | $SET);
sub unpack_set {
my ($in, $tag, $allowed) = @_;
$in = unpack_body($in, $tag, $CONS | $SET);
my @ret;
my $tagbody;
while ($in ne '') {
($in, undef, undef, $tagbody) = asn1_unpack($in, $allowed);
($in, undef, undef, $tagbody) = unpack_raw($in, $allowed);
push @ret, $tagbody;
}
return @ret;
}

sub asn1_unpack_bytes {
my $in = asn1_unpack_body($_[0], $_[1], $BIT_STRING);
sub unpack_bytes {
my $in = unpack_body($_[0], $_[1], $BIT_STRING);
die("unpack_bytes: bit number not multiple of 8\n") unless unpack('C', $in) == 0;
return substr($in, 1);
}

sub asn1_unpack_octet_string {
return asn1_unpack_body($_[0], $_[1], $OCTET_STRING);
sub unpack_octet_string {
return unpack_body($_[0], $_[1], $OCTET_STRING);
}

sub asn1_unpack_string {
my ($in, $intag) = @_;
$intag = [ $UTF8STRING, $NUMERICSTRING, $PRINTABLESTRING, $IA5STRING, $BMPSTRING, $UNIVERSALSTRING ] unless defined $intag;
my (undef, $tag, $in) = asn1_unpack($in, $intag, undef, 1);
sub unpack_string {
my ($in, $tag) = @_;
$tag = [ $UTF8STRING, $NUMERICSTRING, $PRINTABLESTRING, $IA5STRING, $BMPSTRING, $UNIVERSALSTRING ] unless defined $tag;
(undef, $tag, $in) = unpack_raw($in, $tag, undef, 1);
if ($tag == $BMPSTRING) {
$in = Encode::decode('UCS-2BE', $in);
Encode::_utf8_off($in);
Expand All @@ -277,8 +277,8 @@ sub asn1_unpack_string {
return $in;
}

sub asn1_unpack_bits_list {
my $in = asn1_unpack_body($_[0], $_[1], $BIT_STRING);
sub unpack_bits_list {
my $in = unpack_body($_[0], $_[1], $BIT_STRING);
my $empty = unpack('C', $in);
die("unpack_bits: empty bits not in range 0..7\n") if $empty > 7;
$in = unpack('B*', substr($in, 1));
Expand All @@ -288,13 +288,13 @@ sub asn1_unpack_bits_list {
return @res;
}

sub asn1_unpack_boolean {
my $in = asn1_unpack_body($_[0], $_[1], $BOOLEAN);
sub unpack_boolean {
my $in = unpack_body($_[0], $_[1], $BOOLEAN);
return unpack('C', $in) ? 1 : 0;
}

sub asn1_unpack_tagged {
return asn1_unpack_body($_[0], $_[1], 0);
sub unpack_tagged {
return unpack_body($_[0], $_[1], 0);
}

1;
30 changes: 15 additions & 15 deletions src/backend/BSTUF.pm
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ use strict;
sub keydata2asn1 {
my ($keydata) = @_;
die("need an rsa pubkey\n") unless ($keydata->{'algo'} || '') eq 'rsa';
my $pubkey = BSASN1::asn1_sequence(BSASN1::asn1_integer_mpi($keydata->{'mpis'}->[0]->{'data'}), BSASN1::asn1_integer_mpi($keydata->{'mpis'}->[1]->{'data'}));
return BSASN1::asn1_sequence(BSASN1::asn1_sequence($BSX509::oid_rsaencryption, BSASN1::asn1_null()), BSASN1::asn1_bytes($pubkey));
my $pubkey = BSASN1::pack_sequence(BSASN1::pack_integer_mpi($keydata->{'mpis'}->[0]->{'data'}), BSASN1::pack_integer_mpi($keydata->{'mpis'}->[1]->{'data'}));
return BSASN1::pack_sequence(BSASN1::pack_sequence($BSX509::oid_rsaencryption, BSASN1::pack_null()), BSASN1::pack_bytes($pubkey));
}

sub rfc3339time {
Expand All @@ -62,50 +62,50 @@ sub sign {

sub mktbscert {
my ($cn, $not_before, $not_after, $subjectkeyinfo) = @_;
my $certversion = BSASN1::asn1_tagged(0, BSASN1::asn1_integer(2));
my $certversion = BSASN1::pack_tagged(0, BSASN1::pack_integer(2));
my $certserial = BSX509::pack_random_serial();
my $sigalgo = BSASN1::asn1_sequence($BSX509::oid_sha256withrsaencryption, BSASN1::asn1_null());
my $sigalgo = BSASN1::pack_sequence($BSX509::oid_sha256withrsaencryption, BSASN1::pack_null());
my $issuer = BSX509::pack_distinguished_name([ $BSX509::oid_common_name, $cn ]);
my $validity = BSASN1::asn1_sequence(BSASN1::asn1_utctime($not_before), BSASN1::asn1_utctime($not_after));
my $basic_constraints = BSASN1::asn1_sequence();
my $key_usage = BSASN1::asn1_bits_list($BSX509::key_usage_digital_signature, $BSX509::key_usage_key_encipherment);
my $ext_key_usage = BSASN1::asn1_sequence($BSX509::oid_code_signing);
my $validity = BSASN1::pack_sequence(BSASN1::pack_utctime($not_before), BSASN1::pack_utctime($not_after));
my $basic_constraints = BSASN1::pack_sequence();
my $key_usage = BSASN1::pack_bits_list($BSX509::key_usage_digital_signature, $BSX509::key_usage_key_encipherment);
my $ext_key_usage = BSASN1::pack_sequence($BSX509::oid_code_signing);
my $extensions = BSX509::pack_cert_extensions(
$BSX509::oid_basic_constraints, [ $basic_constraints, 1 ],
$BSX509::oid_key_usage, [ $key_usage, 1 ],
$BSX509::oid_ext_key_usage, [ $ext_key_usage ]);
my $tbscert = BSASN1::asn1_sequence($certversion, $certserial, $sigalgo, $issuer, $validity, $issuer, $subjectkeyinfo, $extensions);
my $tbscert = BSASN1::pack_sequence($certversion, $certserial, $sigalgo, $issuer, $validity, $issuer, $subjectkeyinfo, $extensions);
return $tbscert;
}

sub mkcert {
my ($tbscert, $signargs) = @_;
my $signature = sign($tbscert, $signargs);
my $sigalgo = BSASN1::asn1_sequence($BSX509::oid_sha256withrsaencryption, BSASN1::asn1_null());
my $cert = BSASN1::asn1_sequence($tbscert, $sigalgo, BSASN1::asn1_bytes($signature));
my $sigalgo = BSASN1::pack_sequence($BSX509::oid_sha256withrsaencryption, BSASN1::pack_null());
my $cert = BSASN1::pack_sequence($tbscert, $sigalgo, BSASN1::pack_bytes($signature));
return BSASN1::der2pem($cert, 'CERTIFICATE');
}

# return the to-be-signed part of a certificate
sub gettbscert {
my ($cert) = @_;
$cert = BSASN1::pem2der($cert, 'CERTIFICATE');
return (BSASN1::asn1_unpack_sequence($cert, undef, [ $BSASN1::CONS | $BSASN1::SEQUENCE, -1]))[0];
return (BSASN1::unpack_sequence($cert, undef, [ $BSASN1::CONS | $BSASN1::SEQUENCE, -1]))[0];
}

# remove the serial number from a tbs certificate. We need to do this because the
# serial is random and we want to compare two certs.
sub removecertserial {
my ($tbscert) = @_;
my @parts = BSASN1::asn1_unpack_sequence($tbscert, undef, [ @$BSX509::tbscertificate_tags[0 .. 1], -1 ]);
my @parts = BSASN1::unpack_sequence($tbscert, undef, [ @$BSX509::tbscertificate_tags[0 .. 1], -1 ]);
splice(@parts, 1, 1); # remove serial entry
return BSASN1::asn1_sequence(@parts);
return BSASN1::pack_sequence(@parts);
}

# get pubkey
sub getsubjectkeyinfo {
my ($tbscert) = @_;
return (BSASN1::asn1_unpack_sequence($tbscert, undef, [ @$BSX509::tbscertificate_tags[0 .. 7], -1 ]))[6];
return (BSASN1::unpack_sequence($tbscert, undef, [ @$BSX509::tbscertificate_tags[0 .. 7], -1 ]))[6];
}

sub signdata {
Expand Down

0 comments on commit 56cbb1e

Please sign in to comment.