add support for x509pem as a pkc type (addressing MS #2566)
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Thu, 28 Oct 2010 22:44:01 +0000 (18:44 -0400)
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Thu, 28 Oct 2010 22:44:01 +0000 (18:44 -0400)
Crypt/Monkeysphere/MSVA.pm
Crypt/Monkeysphere/MSVA/Client.pm

index c0858e0c0d54c782c848cbbfb728b2de4eb967cc..55dc5bca56ba2e713a2547c1a58843d56596f822 100755 (executable)
     return 0;
   }
 
+  sub pem2der {
+    my $pem = shift;
+    my @lines = split(/\n/, $pem);
+    my @goodlines = ();
+    my $ready = 0;
+    use MIME::Base64;
+    foreach my $line (@lines) {
+      if ($ready) {
+        push @goodlines, $line;
+      } elsif ($line eq '-----BEGIN CERTIFICATE-----') {
+        $ready = 1;
+      } elsif ($line eq '-----END CERTIFICATE-----') {
+        last;
+      }
+    }
+    return decode_base64(join('', @goodlines));
+  }
+
   sub getuid {
     my $data = shift;
     if ($data->{context} =~ /^(https|ssh)$/) {
     msvalog('verbose', "context: %s\n", $data->{context});
     msvalog('verbose', "peer: %s\n", $data->{peer});
 
-    my $rawdata = join('', map(chr, @{$data->{pkc}->{data}}));
+    my $rawdata;
+    if ($data->{pkc}->{type} eq 'x509der') {
+      $rawdata = join('', map(chr, @{$data->{pkc}->{data}}));
+    } elsif ($data->{pkc}->{type} eq 'x509pem') {
+      $rawdata = pem2der($data->{pkc}->{data});
+    } else {
+      $ret->{message} = sprintf("Don't know this public key carrier type: %s", $data->{pkc}->{type});
+      return $status,$ret;
+    }
     my $cert = Crypt::X509->new(cert => $rawdata);
 
+    if ($cert->error) {
+      $ret->{message} = sprintf("Error decoding X.509 certificate: %s", $cert->error);
+      return $status, $ret;
+    }
     msvalog('verbose', "cert subject: %s\n", $cert->subject_cn());
     msvalog('verbose', "cert issuer: %s\n", $cert->issuer_cn());
     msvalog('verbose', "cert pubkey algo: %s\n", $cert->PubKeyAlg());
                );
 
         if ($key->{modulus}->copy()->blog(2) < 1000) { # FIXME: this appears to be the full pubkey, including DER overhead
-          $ret->{message} = sprintf('public key size is less than 1000 bits (was: %d bits)', $cert->pubkey_size());
+          $ret->{message} = sprintf('Public key size is less than 1000 bits (was: %d bits)', $cert->pubkey_size());
         } else {
           $ret->{message} = sprintf('Failed to validate "%s" through the OpenPGP Web of Trust.', $uid);
           my $lastloop = 0;
index d657a982ac73066b0adad1f0a8042abf4a25daff..a6d1ed7d312d34f65066fd92daa8ccb0bad619b2 100644 (file)
@@ -86,6 +86,8 @@
     $self->log('debug', "peer: %s\n", $peer);
     $self->log('debug', "pkctype: %s\n", $pkctype);
 
+    my $transformed_data;
+
     if ($pkctype eq 'x509der') {
       if ($self->{logger}->is_logging_at('verbose')) {
         if (Module::Load::Conditional::can_load('modules' => { 'Crypt::X509' => undef })) {
           $self->log('verbose', "X.509 cert going to agent but we cannot inspect it without Crypt::X509\n");
         }
       }
+      # remap raw pkc data into numeric array
+      $transformed_data = [map(ord, split(//,$pkcdata))];
+    } elsif ($pkctype eq 'x509pem') {
+      $transformed_data = $pkcdata;
     } else {
-       $self->log('error', "unknown pkc type '%s'.\n", $pkctype);
+      $self->log('error', "unknown pkc type '%s'.\n", $pkctype);
     };
 
     return {
             peer => $peer,
             pkc => {
                     type => $pkctype,
-                    # remap raw pkc data into numeric array
-                    data => [map(ord, split(//,$pkcdata))],
+                    data => $transformed_data,
                    },
            };
   };