summaryrefslogtreecommitdiffstats
path: root/base/ra/lib/perl/PKI/Conn/CA.pm
diff options
context:
space:
mode:
Diffstat (limited to 'base/ra/lib/perl/PKI/Conn/CA.pm')
-rw-r--r--base/ra/lib/perl/PKI/Conn/CA.pm390
1 files changed, 390 insertions, 0 deletions
diff --git a/base/ra/lib/perl/PKI/Conn/CA.pm b/base/ra/lib/perl/PKI/Conn/CA.pm
new file mode 100644
index 000000000..f3c8834ed
--- /dev/null
+++ b/base/ra/lib/perl/PKI/Conn/CA.pm
@@ -0,0 +1,390 @@
+#!/usr/bin/perl
+#
+# --- BEGIN COPYRIGHT BLOCK ---
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2007 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+#
+#
+#
+package PKI::Conn::CA;
+
+use URI::URL;
+use URI::Escape;
+use XML::Simple;
+use Data::Dumper;
+use DBI;
+use PKI::Base::TimeTool;
+use PKI::Base::CertStore;
+use PKI::Base::Util;
+use PKI::Request::Queue;
+
+#######################################
+# Constructs a request queue
+#######################################
+sub new {
+ my $self = {};
+ bless ($self);
+ return $self;
+}
+
+#######################################
+# Opens request queue
+#######################################
+sub open {
+ my ($self, $cfg) = @_;
+ $self->{cfg} = $cfg;
+ my $certstore = PKI::Base::CertStore->new();
+ $certstore->open($cfg);
+ $self->{certstore} = $certstore;
+}
+
+#######################################
+# Enrolls
+#######################################
+sub enroll {
+ my ($self, $rid, $con_id, $profile_id, $cert_request_type, $cert_request) = @_;
+
+ my $cfg = $self->{cfg};
+ my $instdir = $cfg->get("service.instanceDir");
+ my $db_password;
+
+ my $nickname = $cfg->get("conn." . $con_id . ".clientNickname");
+ my $cahostport = $cfg->get("conn." . $con_id . ".hostport");
+ my ($host, $port) = split(/:/, $cahostport);
+
+ if ($nickname =~ /(.*):(.*)/) {
+ $db_password = `grep \"$1:\" \"$instdir/conf/password.conf\" | awk -F: '{print \$2}'`;
+ } else {
+ $db_password = `grep \"internal:\" \"$instdir/conf/password.conf\" | cut -c10-`;
+ }
+ $db_password =~ s/\n$//g;
+
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ my $req = $queue->read_request($rid);
+ if ($req->{'subject_dn'} ne "unavailable") {
+ $subject = $req->{'subject_dn'};
+ }
+
+ my $tmpfile = "/tmp/tmp-$rid-$$";
+ my $params = "profileId=" . $profile_id . "&" .
+ "requestor_name=" .
+ URI::Escape::uri_escape("$requestor_name") . "&" .
+ "cert_request_type=" . $cert_request_type . "&" .
+ "subject=" .
+ URI::Escape::uri_escape("$subject") . "&" .
+ "cert_request=" .
+ URI::Escape::uri_escape("$cert_request") . "&" .
+ "xmlOutput=true";
+
+ system("/usr/bin/sslget -e \"$params\" -d \"$instdir/alias\" -p \"$db_password\" -v -n \"$nickname\" -r \"/ca/ee/ca/profileSubmit\" $host:$port > $tmpfile");
+
+ my $content = `cat $tmpfile`;
+ if ($content eq "") {
+ $queue->set_request($rid, "errorString", "CA Connection Error");
+ $queue->set_request($rid, "status", "ERROR");
+ $queue->close();
+
+ $queue->close();
+ return "";
+ }
+
+ $content =~ /(\<XMLResponse\>.*\<\/XMLResponse\>)/;
+ $content = $1;
+ $content =~ s/\n//g;
+
+ my $xmlparser = XML::Simple->new();
+ my $response = $xmlparser->XMLin($content);
+
+ my $status = $response->{Status};
+ if ($status ne "0") {
+ my $errorString = $response->{Error};
+
+ $queue->set_request($rid, "errorString", "CA: ".$errorString);
+ $queue->set_request($rid, "status", "ERROR");
+
+ $queue->close();
+ return "";
+ }
+
+ #reset to 0 in case of re-approval
+ $queue->set_request($rid, "errorString", "0");
+ my $req = $queue->read_request($rid);
+ my $approved_by = $req->{'processed_by'};
+ my $serialno = $response->{Requests}->{Request}->{serialno};
+ $queue->set_request($rid, "serialno", $serialno);
+ my $subject_dn = $response->{Requests}->{Request}->{SubjectDN};
+ $queue->set_request($rid, "subject_dn", $subject_dn);
+ my $cert = $response->{Requests}->{Request}->{b64};
+ $queue->close();
+
+ my $util = PKI::Base::Util->new();
+ my $csr = $cert_request;
+ $csr = $util->normalize_csr($csr);
+
+ $self->{certstore}->add_certificate($serialno, $csr, $subject_dn, $cert, $rid, $approved_by);
+
+ system("rm $tmpfile");
+
+ return $cert;
+}
+
+sub get_http_content
+{
+ my ($self, $filename) = @_;
+ my $data = "";
+ my $count = `grep -a Content-Length $filename | cut -d' ' -f2`;
+ chomp($count);
+ my $file_size = -s $filename;
+ my $offset = $file_size - $count;
+
+ open(FP, "<$filename");
+ binmode(FP);
+ seek(FP, $offset-1, 0);
+ read(FP, $data, $count);
+ close(FP);
+ return $data;
+}
+
+#######################################
+# Revoke
+#######################################
+sub revoke {
+ my ($self, $rid, $con_id, $serialno, $reason) = @_;
+
+ my $cfg = $self->{cfg};
+ my $instdir = $cfg->get("service.instanceDir");
+ my $db_password;
+
+ my $nickname = $cfg->get("conn." . $con_id . ".clientNickname");
+ my $cahostport = $cfg->get("conn." . $con_id . ".hostagentport");
+
+ if ($nickname =~ /(.*):(.*)/) {
+ $db_password = `grep \"$1:\" \"$instdir/conf/password.conf\" | awk -F: '{print \$2}'`;
+ } else {
+ $db_password = `grep \"internal:\" \"$instdir/conf/password.conf\" | cut -c10-`;
+ }
+ $db_password =~ s/\n$//g;
+
+ my $tmpfile = "/tmp/tmp-revoke-$serialno-$$";
+ my ($host, $port) = split(/:/, $cahostport);
+ my $params = "op=" . "revoke" . "&" .
+ "revocationReason=" .$reason . "&" .
+ "revokeAll=(certRecordId=" ."0x".$serialno . ")&" .
+ "totalRecordCount=" ."1" . "&" .
+ "xml=true";
+ system("/usr/bin/sslget -e \"$params\" -d \"$instdir/alias\" -p \"$db_password\" -v -n \"$nickname\" -r \"/ca/agent/ca/doRevoke\" $host:$port > $tmpfile");
+
+ my $content = `cat $tmpfile`;
+ my $queue = PKI::Request::Queue->new();
+ $queue->open($cfg);
+ if ($content eq "") {
+ $queue->set_request($rid, "errorString", "CA Connection Error");
+# $queue->set_request($rid, "status", "ERROR");
+ $queue->close();
+
+ $queue->close();
+ return "";
+ }
+ $content =~ s/\000//;
+ $content =~ /(\<xml\>.*\<\/xml\>)/s;
+ $content = $1;
+ $content =~ s/\n//g;
+
+ my $req = $queue->read_request($rid);
+
+ my $xmlparser = XML::Simple->new(NormalizeSpace => 2);
+ my $response = $xmlparser->XMLin($content);
+
+ my $errorString = $response->{fixed}->{errorDetails};
+ my $revoked = $response->{header}->{revoked};
+
+ if ($revoked ne "yes") {
+ $queue->set_request($rid, "errorString", "CA:".$errorString);
+ } else {
+ $queue->set_request($rid, "errorString", "0");
+ }
+ system("rm $tmpfile");
+
+ $queue->close();
+ return;
+}
+
+#######################################
+# Get Certificate Status
+#######################################
+sub getCertStatus {
+ my ($self, $con_id, $serialno) = @_;
+
+ my $cfg = $self->{cfg};
+ my $instdir = $cfg->get("service.instanceDir");
+ my $db_password;
+
+ my $nickname = $cfg->get("conn." . $con_id . ".clientNickname");
+ my $cahostport = $cfg->get("conn." . $con_id . ".hostport");
+ my ($host, $port) = split(/:/, $cahostport);
+
+ if ($nickname =~ /(.*):(.*)/) {
+ $db_password = `grep \"$1:\" \"$instdir/conf/password.conf\" | awk -F: '{print \$2}'`;
+ } else {
+ $db_password = `grep \"internal:\" \"$instdir/conf/password.conf\" | cut -c10-`;
+ }
+ $db_password =~ s/\n$//g;
+
+
+ my $tmpfile = "/tmp/tmp-$serialno-$$";
+ my $params = "serialNumber=" . "0x".$serialno . "&" .
+ "xml=true";
+ system("/usr/bin/sslget -e \"$params\" -d \"$instdir/alias\" -p \"$db_password\" -v -n \"$nickname\" -r \"/ca/ee/ca/displayBySerial\" $host:$port > $tmpfile");
+
+ my $content = `cat $tmpfile`;
+ system("rm $tmpfile");
+ if ($content eq "") {
+ return "CA: Connection Error";
+ system("rm $tmpfile");
+ }
+
+ $content =~ /(\<xml\>.*\<\/xml\>)/s;
+ $content = $1;
+ $content =~ s/\n//g;
+
+ my $xmlparser = XML::Simple->new(NormalizeSpace => 2);
+ my $response = $xmlparser->XMLin($content);
+
+ my $errorString = $response->{fixed}->{errorDetails};
+ my $revokeReason = $response->{header}->{revocationReason};
+
+ if ($revokeReason eq "") {
+ if ($errorString eq "") {
+ return "not revoked";
+ } else {
+ return "CA:".$errorString;
+ }
+ } else {
+ return "revoked:".$revokeReason;
+ }
+}
+
+#######################################
+# SCEP
+#######################################
+sub scep_get_ca_cert {
+ my ($self, $con_id, $operation, $message) = @_;
+
+ my $cfg = $self->{cfg};
+ my $instdir = $cfg->get("service.instanceDir");
+ my $db_password;
+
+ my $nickname = $cfg->get("conn." . $con_id . ".clientNickname");
+ my $cahostport = $cfg->get("conn." . $con_id . ".hostport");
+ my ($host, $port) = split(/:/, $cahostport);
+
+ if ($nickname =~ /(.*):(.*)/) {
+ $db_password = `grep \"$1:\" \"$instdir/conf/password.conf\" | awk -F: '{print \$2}'`;
+ } else {
+ $db_password = `grep \"internal:\" \"$instdir/conf/password.conf\" | cut -c10-`;
+ }
+ $db_password =~ s/\n$//g;
+
+ my $tmpfile = "/tmp/tmp-$$";
+ my $params = "operation=" . $operation . "&" .
+ "message=" . $message;
+ system("/usr/bin/sslget -e \"$params\" -d \"$instdir/alias\" -p \"$db_password\" -n \"$nickname\" -r \"/ca/ee/ca/pkiclient\" $host:$port > $tmpfile");
+
+
+ my $content = $self->get_http_content($tmpfile);
+
+ system("rm $tmpfile");
+
+ return $content;
+}
+
+# decode PKI Message
+sub scep_decode {
+ my ($self, $con_id, $operation, $message) = @_;
+
+ my $cfg = $self->{cfg};
+ my $instdir = $cfg->get("service.instanceDir");
+ my $db_password;
+
+ my $nickname = $cfg->get("conn." . $con_id . ".clientNickname");
+ my $cahostport = $cfg->get("conn." . $con_id . ".hostport");
+ my ($host, $port) = split(/:/, $cahostport);
+
+ if ($nickname =~ /(.*):(.*)/) {
+ $db_password = `grep \"$1:\" \"$instdir/conf/password.conf\" | awk -F: '{print \$2}'`;
+ } else {
+ $db_password = `grep \"internal:\" \"$instdir/conf/password.conf\" | cut -c10-`;
+ }
+ $db_password =~ s/\n$//g;
+
+ my $tmpfile = "/tmp/tmp-$$";
+ my $params = "operation=" . $operation . "&" .
+ "message=" . $message . "&" .
+ "decode=true";
+ system("/usr/bin/sslget -e \"$params\" -d \"$instdir/alias\" -p \"$db_password\" -n \"$nickname\" -r \"/ca/ee/ca/pkiclient\" $host:$port > $tmpfile");
+
+
+ my $content = $self->get_http_content($tmpfile);
+
+ system("rm $tmpfile");
+
+ return $content;
+}
+
+sub scep_pki_message {
+ my ($self, $con_id, $operation, $message) = @_;
+
+ my $cfg = $self->{cfg};
+ my $instdir = $cfg->get("service.instanceDir");
+ my $db_password;
+
+ my $nickname = $cfg->get("conn." . $con_id . ".clientNickname");
+ my $cahostport = $cfg->get("conn." . $con_id . ".hostport");
+ my ($host, $port) = split(/:/, $cahostport);
+
+ if ($nickname =~ /(.*):(.*)/) {
+ $db_password = `grep \"$1:\" \"$instdir/conf/password.conf\" | awk -F: '{print \$2}'`;
+ } else {
+ $db_password = `grep \"internal:\" \"$instdir/conf/password.conf\" | cut -c10-`;
+ }
+ $db_password =~ s/\n$//g;
+
+ my $tmpfile = "/tmp/tmp-$$";
+ my $params = "operation=" . $operation . "&" .
+ "message=" . $message;
+ system("/usr/bin/sslget -e \"$params\" -d \"$instdir/alias\" -p \"$db_password\" -n \"$nickname\" -r \"/ca/ee/ca/pkiclient\" $host:$port > $tmpfile");
+
+
+ my $content = $self->get_http_content($tmpfile);
+
+ system("rm $tmpfile");
+
+ return $content;
+}
+
+
+#######################################
+# Closes connection
+#######################################
+sub close {
+ my ($self) = @_;
+ $self->{certstore}->close();
+}
+
+1;