hello
i've made a small fix for the error. in OpenCA::REQ->parseReq when
splitting $textReq there appears one empty $key when approving the request
with internet explorer.
attached please find original REQ.pm.orig and fixed REQ.pm.fixed.
have a nice day,
martin lizner
www.anect.com
czech rep.
On Fri, 14 Feb 2003, Martin Lizner wrote:
> hello
>
> i am not able to track down and correct error while approving SPKAC
> requests on RA with Internet Explorer browser. i use openca-0.9.1-RC5.
>
> i get this message:
>
> Can't call method "getRDNs" on an undefined value at
> /usr/lib/perl5/site_perl/5.6.1/OpenCA/REQ.pm line 544.
> Compilation failed in require at /usr/local/apache/cgi-bin/ra/RAServer
> line 213.
>
> i can approve it only with netscape. thank you for any hints,
>
> martin lizner
> www.anect.com
> czech rep.
>
>
## OpenCA::REQ
##
## Copyright (C) 1998-1999 Massimiliano Pala ([EMAIL PROTECTED])
## All rights reserved.
##
## This library is free for commercial and non-commercial use as long as
## the following conditions are aheared to. The following conditions
## apply to all code found in this distribution, be it the RC4, RSA,
## lhash, DES, etc., code; not just the SSL code. The documentation
## included with this distribution is covered by the same copyright terms
##
## Copyright remains Massimiliano Pala's, and as such any Copyright notices
## in the code are not to be removed.
## If this package is used in a product, Massimiliano Pala should be given
## attribution as the author of the parts of the library used.
## This can be in the form of a textual message at program startup or
## in documentation (online or textual) provided with the package.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
## are met:
## 1. Redistributions of source code must retain the copyright
## notice, this list of conditions and the following disclaimer.
## 2. Redistributions in binary form must reproduce the above copyright
## notice, this list of conditions and the following disclaimer in the
## documentation and/or other materials provided with the distribution.
## 3. All advertising materials mentioning features or use of this software
## must display the following acknowledgement:
## "This product includes OpenCA software written by Massimiliano Pala
## ([EMAIL PROTECTED]) and the OpenCA Group (www.openca.org)"
## 4. If you include any Windows specific code (or a derivative thereof) from
## some directory (application code) you must include an acknowledgement:
## "This product includes OpenCA software (www.openca.org)"
##
## THIS SOFTWARE IS PROVIDED BY OPENCA DEVELOPERS ``AS IS'' AND
## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
## OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
## OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
## SUCH DAMAGE.
##
## The licence and distribution terms for any publically available version or
## derivative of this code cannot be changed. i.e. this code cannot simply be
## copied and put under another distribution licence
## [including the GNU Public Licence.]
##
## moduleerrorcode is 72
##
## functions:
##
## new 11
## initReq 12
## getParsed 21
## getHeader 31
## getSignature 32
## getKey 33
## getBody 34
## getRawHeader 35
## parseReq 13
## getTXT 41
## getPEM 42
## getDER 43
## getItem 51
## getSerial 52
use strict;
use Digest::MD5;
use X500::DN;
package OpenCA::REQ;
our ($errno, $errval);
($OpenCA::REQ::VERSION = '$Revision: 1.36 $' )=~ s/(?:^.*: (\d+))|(?:\s+\$$)/defined
$1?"0\.9":""/eg;
my %params = (
req => undef,
item => undef,
pemREQ => undef,
derREQ => undef,
txtREQ => undef,
spkacREQ => undef,
revokeREQ => undef,
parsedSPKAC => undef,
parsedCRR => undef,
parsedItem => undef,
backend => undef,
beginHeader => undef,
endHeader => undef,
beginSignature => undef,
endSignature => undef,
beginKey => undef,
endKey => undef,
reqFormat => undef,
);
sub setError {
my $self = shift;
if (scalar (@_) == 4) {
my $keys = { @_ };
$errval = $keys->{ERRVAL};
$errno = $keys->{ERRNO};
} else {
$errno = $_[0];
$errval = $_[1];
}
## support for: return $self->setError (1234, "Something fails.") if (not
$xyz);
return undef;
}
sub new {
my $that = shift;
my $class = ref($that) || $that;
my $self = {
%params,
};
bless $self, $class;
$self->{beginHeader} = "-----BEGIN HEADER-----";
$self->{endHeader} = "-----END HEADER-----";
$self->{beginSignature} = "-----BEGIN PKCS7-----";
$self->{endSignature} = "-----END PKCS7-----";
$self->{beginKey} = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
$self->{endKey} = "-----END ENCRYPTED PRIVATE KEY-----";
$self->{reqFormat} = "";
my $keys = { @_ };
my ( $infile, $keyfile, $tmp );
$self->{req} = $keys->{DATA};
$self->{reqFormat} = ( $keys->{FORMAT} or $keys->{INFORM} );
$self->{backend} = $keys->{SHELL};
$infile = $keys->{INFILE};
$keyfile = $keys->{KEYFILE};
return $self->setError (7211011, "OpenCA::REQ->new: The backend is not
specified.") if (not $self->{backend});
if( $keyfile ) {
if ( not defined $self->{reqFormat} or not $self->{reqFormat} ) {
$self->{reqFormat} = "PEM";
}
$self->{req} = $self->{backend}->genReq( KEYFILE=>$keys->{KEYFILE},
DN=>$keys->{DN},
SUBJECT=>$keys->{SUBJECT},
OUTFORM=>$self->{reqFormat},
PASSWD=>$keys->{PASSWD} );
return $self->setError (7211021,
"OpenCA::REQ->new: Cannot create new request.\n".
"Backend fails with errorcode ".$OpenCA::OpenSSL::errno."\n".
$OpenCA::OpenSSL::errval)
if ( not $self->{req} );
}
if( $infile ) {
$self->{req} = "";
open(FD, "<$infile" ) or
return $self->setError (7211031,
"OpenCA::REQ->new: Cannot open infile
$infile for reading.");
while ( $tmp = <FD> ) {
$self->{req} .= $tmp;
}
close(FD);
return $self->setError (7211033, "Cannot read request from infile
$infile.")
if( not $self->{req});
}
if( not (defined($self->{reqFormat})) or ($self->{reqFormat} eq "")) {
if( ( $self->{req} ) and ( $self->{req} =~ /SPKAC\s*=\s*/g ) ){
$self->{reqFormat} = "SPKAC";
} elsif (($self->{req}) and ($self->{req} =~
/REVOKE_CERTIFICATE_SERIAL\s*=\s*/g)){
$self->{reqFormat} = "CRR";
} else {
$self->{reqFormat} = "PEM";
}
}
if ( $self->{req} ne "" ) {
$self->{item} = $self->{req};
if ( not $self->initReq( REQ=>$self->{req},
FORMAT=>$self->{reqFormat})) {
return $self->setError (7211041,
"OpenCA::REQ->new: Cannot initialize request
(".$errno.")\n".$errval);
}
}
return $self;
}
sub initReq {
my $self = shift;
my $keys = { @_ };
$self->{reqFormat} = $keys->{FORMAT};
$self->{req} = $self->getBody( REQUEST=> $keys->{REQ});
if (not $self->{req}) {
$self->{parsedItem} = $self->parseReq( REQ=>$keys->{REQ},
FORMAT=>$self->{reqFormat} );
return $self->setError (7212011, "OpenCA::REQ->initReq: Cannot parse
request ".
"($errno):\n$errval")
if (not $self->{parsedItem});
} elsif( $self->{reqFormat} !~ /SPKAC|CRR/i ) {
$self->{pemREQ} = $self->{backend}->dataConvert(
DATA=>$self->{req},
DATATYPE=>"REQUEST",
INFORM=>$self->{reqFormat},
OUTFORM=>"PEM" );
return $self->setError (7212021, "OpenCA::REQ->initReq: Cannot convert
request to PEM-format ".
"(".$OpenCA::OpenSSL::errno."):\n".
$OpenCA::OpenSSL::errval)
if (not $self->{pemREQ});
$self->{derREQ} = $self->{backend}->dataConvert(
DATA=>$self->{req},
DATATYPE=>"REQUEST",
INFORM=>$self->{reqFormat},
OUTFORM=>"DER" );
return $self->setError (7212022, "OpenCA::REQ->initReq: Cannot convert
request to DER-format ".
"(".$OpenCA::OpenSSL::errno."):\n".
$OpenCA::OpenSSL::errval)
if (not $self->{derREQ});
$self->{txtREQ} = $self->{backend}->dataConvert(
DATA=>$self->{req},
DATATYPE=>"REQUEST",
INFORM=>$self->{reqFormat},
OUTFORM=>"TXT" );
return $self->setError (7212023, "OpenCA::REQ->initReq: Cannot convert
request to TXT-format ".
"(".$OpenCA::OpenSSL::errno."):\n".
$OpenCA::OpenSSL::errval)
if (not $self->{txtREQ});
$self->{parsedItem} = $self->parseReq( REQ=>$keys->{REQ},
FORMAT=>$self->{reqFormat} );
return $self->setError (7212024, "OpenCA::REQ->initReq: Cannot parse
request ".
"($errno):\n$errval")
if (not $self->{parsedItem});
} else {
if ( $self->{reqFormat} =~ /SPKAC/ ) {
$self->{spkacREQ} = $self->{req};
$self->{parsedSPKAC}=$self->parseReq( REQ=>$keys->{REQ},
FORMAT=>"SPKAC" );
$self->{parsedItem} = $self->{parsedSPKAC};
return $self->setError (7212026, "OpenCA::REQ->initReq: Cannot
parse request ".
"($errno):\n$errval")
if( not $self->{parsedSPKAC} );
} elsif ( $self->{reqFormat} =~ /CRR/ ) {
$self->{revokeREQ} = $self->{req};
$self->{parsedCRR}=
$self->parseReq( REQ=>$keys->{REQ},
FORMAT=>"CRR" );
$self->{parsedItem} = $self->{parsedCRR};
return $self->setError (7212031, "OpenCA::REQ->initReq: Cannot
parse request ".
"($errno):\n$errval")
if( not $self->{parsedCRR} );
} else {
return $self->setError (7212041, "OpenCA::REQ->initReq:
Unknown request's format.");
}
}
return 1;
}
sub getParsed {
my $self = shift;
if( $self->{reqFormat} =~ /SPKAC/i ) {
return $self->setError (7221011, "OpenCA::REQ->getParsed:
SPKAC-request was not parsed.")
if( not $self->{parsedSPKAC} );
return $self->{parsedSPKAC};
} elsif( $self->{reqFormat} =~ /CRR/i ) {
return $self->setError (7221013, "OpenCA::REQ->getParsed: CRR was not
parsed.")
if( not $self->{parsedCRR} );
return $self->{parsedCRR};
} else {
return $self->setError (7221014, "OpenCA::REQ->getParsed: Request was
not parsed.")
if ( not $self->{parsedItem} );
return $self->{parsedItem};
}
}
sub getHeader {
my $self = shift;
my $keys = { @_ };
my $req = $keys->{REQUEST};
my ( $txt, $ret, $i, $key, $val );
my $beginHeader = $self->{beginHeader};
my $endHeader = $self->{endHeader};
if( ($txt) = ( $req =~ /$beginHeader\s*\n([\s\S\n]+)\n$endHeader/) ) {
foreach $i ( split ( /\s*\n/, $txt ) ) {
## fix CR
$i =~ s/\s*\r$//;
$i =~ s/\s*=\s*/=/;
( $key, $val ) = ( $i =~ /^([^=]*)\s*=\s*(.*)\s*/ );
$ret->{$key} = $val;
## fix old requests
if ($key eq "SUBJ") {
$ret->{SUBJECT} = $val;
}
}
}
return $ret;
}
sub getRawHeader {
my $self = shift;
my $keys = { @_ };
my $req = $keys->{REQUEST};
my $beginHeader = $self->{beginHeader};
my $endHeader = $self->{endHeader};
my ( $ret ) = ( $req =~ /($beginHeader[\S\s\n]+$endHeader)/ );
return $ret;
}
sub getSignature {
my $self = shift;
my $keys = { @_ };
my $req = $keys->{REQUEST};
my $beginSig = $self->{beginSignature};
my $endSig = $self->{endSignature};
my ( $ret ) = ( $req =~ /($beginSig[\S\s\n]+$endSig)/ );
return $ret;
}
sub getKey {
my $self = shift;
my $keys = { @_ };
my $req = $keys->{REQUEST};
my $beginKey = $self->{beginKey};
my $endKey = $self->{endKey};
my ( $ret ) = ( $req =~ /($beginKey[\S\s\n]+$endKey)/ );
return $ret;
}
sub getBody {
my $self = shift;
my $keys = { @_ };
my $ret = $keys->{REQUEST};
my $beginHeader = $self->{beginHeader};
my $endHeader = $self->{endHeader};
my $beginSig = $self->{beginSignature};
my $endSig = $self->{endSignature};
my $beginKey = $self->{beginKey};
my $endKey = $self->{endKey};
## Let's throw away text between the two headers, included
$ret =~ s/($beginHeader[\S\s\n]+$endHeader\n*)//;
## Let's throw away text between the two headers, included
$ret =~ s/($beginSig[\S\s\n]+$endSig)//;
## Let's throw away text between the two headers, included
$ret =~ s/($beginKey[\S\s\n]+$endKey)//;
$ret =~ s/\n$//;
return $ret;
}
sub parseReq {
my $self = shift;
my $keys = { @_ };
my $fullReq = $keys->{REQ};
my $format = $keys->{FORMAT};
my @dnList = ();
my @exts = ();
my ( $ret, $tmp, $key, $val, $tmpOU, $ra, $textReq );
return $self->setError (7213011, "There is no complete request available.")
if (not $fullReq);
$ret->{SIGNATURE} = $self->getSignature ( REQUEST=>$fullReq );
$ret->{KEY} = $self->getKey ( REQUEST=>$fullReq );
$ret->{HEADER} = $self->getHeader ( REQUEST=>$fullReq );
$ret->{RAWHEADER} = $self->getRawHeader ( REQUEST=>$fullReq );
$ret->{BODY} = $self->getBody ( REQUEST=> $fullReq);
$ret->{ITEM} = $self->{item};
if (not $ret->{BODY}) {
## this must be a request with TYPE == HEADER
print "OpenCA::REQ->parseReq: This is a HEADER only.<br>\n" if
($self->{DEBUG});
if ( not $ret->{HEADER} ) {
return $self->setError (7213015,
"OpenCA::REQ->initReq: The request has no body.");
}
if ( not $ret->{HEADER}->{TYPE} =~ /HEADER/i ) {
return $self->setError (7213016,
"OpenCA::REQ->initReq: The request has no body and has
not the type HEADER.");
}
$ret->{TYPE} = "HEADER";
$ret->{DN} = $ret->{HEADER}->{SUBJECT};
} else {
$textReq = $ret->{BODY};
print "OpenCA::REQ->parseReq: FORMAT: $format<br>\n" if
($self->{DEBUG});
if ( $format !~ /CRR/ ) {
## Get Attributes from openssl directly
my @attrlist;
if ( $format =~ /SPKAC/i ) {
@attrlist = ( "PUBKEY" );
} else {
@attrlist = ( "PUBKEY", "DN" );
}
my $attrs = $self->{backend}->getReqAttribute(
DATA=>$ret->{BODY}. "\n",
ATTRIBUTE_LIST=>\@attrlist,
FORMAT=>$format );
foreach (keys %$attrs ) {
$ret->{$_} = $attrs->{$_};
if ($self->{DEBUG}) {
print "OpenCA::REQ->parseReq: ATTRIBUTE:
".$_."<br>\n";
print "OpenCA::REQ->parseReq: VALUE:
".$ret->{$_}."<br>\n";
}
}
}
if( exists $ret->{PUBKEY} ) {
my $md5 = new Digest::MD5;
$md5->add( $ret->{PUBKEY} );
$ret->{KEY_DIGEST} = $md5->hexdigest();
}
if ( $format =~ /SPKAC/i ) {
## Specific for SPKAC requests...
my ( @reqLines );
@reqLines = split( /\n/ , $textReq );
for $tmp (@reqLines) {
$tmp =~ s/\r$//;
my ($key,$val)=($tmp =~ /([\w]+)\s*=\s*(.*)\s*/ );
$key = uc( $key );
if ($key =~ /SPKAC/i) {
$ret->{SPKAC} = $val;
} else {
$ret->{DN} .= ", " if ($ret->{DN});
$ret->{DN} .= $key."=".$val;
}
}
## Now retrieve the SPKAC crypto infos...
$textReq=$self->{backend}->SPKAC( SPKAC=>$ret->{BODY});
$ret->{VERSION} = 1;
$ret->{TYPE} = 'SPKAC';
} elsif( $format =~ /CRR/i ) {
## Specific for SPKAC requests...
my ( @reqLines );
@reqLines = split( /\n/ , $textReq );
for $tmp (@reqLines) {
$tmp =~ s/\r$//;
($key,$val)=($tmp =~ /([\w]+)\s*=\s*(.*)\s*/ );
$key = uc( $key );
$ret->{$key} = $val;
}
$ret->{VERSION} = 1 if ( not exists $ret->{VERSION});
$ret->{TYPE} = 'CRR';
$ret->{HEADER}->{TYPE} = $ret->{TYPE};
$ret->{REVOKE_CERTIFICATE_DN} =~ s/^\///;
$ret->{REVOKE_CERTIFICATE_DN} =~ s/\/([^=]+)=/, $1=/g;
## allow automatic parsing
$ret->{DN} = $ret->{REVOKE_CERTIFICATE_DN};
} else {
$textReq = $self->{backend}->dataConvert( DATA=>$textReq,
DATATYPE=>"REQUEST", INFORM=>$format, OUTFORM=>"TXT");
return $self->setError (7213021, "OpenCA::REQ->parseReq:
Cannot convert request to text-format ".
"(".$OpenCA::OpenSSL::errno.")\n".$OpenCA::OpenSSL::errval)
if ( not $textReq );
## Specific for NON SPKAC requests ...
# ( $ret->{VERSION} ) = ( $textReq =~ /Version:\s+([a-f\d]+)/i
);
( $ret->{VERSION} ) = ( $textReq =~
/Version:\s+([[:xdigit:]]+\s(\([[:xdigit:]]+x[[:xdigit:]]+\))?)/i );
$ret->{DN} =~ s/\,\s*$//;
## We do not verify signature, here...
## $ret->{VERSION} = 0;
if( exists $ret->{HEADER}->{TYPE} ) {
$ret->{TYPE} = $ret->{HEADER}->{TYPE};
} else {
$ret->{TYPE} = 'PKCS#10';
}
}
}
## load the differnt parts of the DN into DN_HASH
my $x500_dn = X500::DN->ParseRFC2253 ($ret->{DN});
my $rdn;
foreach $rdn ($x500_dn->getRDNs()) {
next if ($rdn->isMultivalued());
my @attr_types = $rdn->getAttributeTypes();
my $type = $attr_types[0];
my $value = $rdn->getAttributeValue ($type);
push (@{$ret->{DN_HASH}->{uc($type)}}, $value);
print "OpenCA::REQ->parseReq: DN_HASH: $type=$value<br>\n" if
($self->{DEBUG});
}
## load the differnt parts of the DN into DN_HASH
if ($ret->{HEADER}->{SUBJECT}) {
my $x500_dn = X500::DN->ParseRFC2253 ($ret->{HEADER}->{SUBJECT});
my $rdn;
foreach $rdn ($x500_dn->getRDNs()) {
next if ($rdn->isMultivalued());
my @attr_types = $rdn->getAttributeTypes();
my $type = $attr_types[0];
my $value = $rdn->getAttributeValue ($type);
push (@{$ret->{SUBJECT_HASH}->{uc($type)}}, $value);
print "OpenCA::REQ->parseReq: DN_HASH: $type=$value<br>\n" if
($self->{DEBUG});
}
}
## show DN to check conformance to RFC 2253
if ($self->{DEBUG}) {
print "OpenCA::REQ->parseReq: TYPE: ".$ret->{TYPE}."<br>\n";
print "OpenCA::REQ->parseReq: DN: ".$ret->{DN}."<br>\n";
}
## set emailaddress
## FIXME: actually we ignore the subject alternative name in the header
## FIXME: this is a BUG
if ($ret->{HEADER}->{SUBJECT_ALT_NAME} and
( ($ret->{HEADER}->{SUBJECT_ALT_NAME} =~ /^\s*email\s*:/i) or
($ret->{HEADER}->{SUBJECT_ALT_NAME} =~ /,\s*email\s*:/i) ) ) {
( $ret->{EMAILADDRESS} ) =
( $ret->{HEADER}->{SUBJECT_ALT_NAME} =~
/^\s*email\s*:\s*([^,]*),?/ );
if (not $ret->{EMAILADDRESS}) {
( $ret->{EMAILADDRESS} ) =
( $ret->{HEADER}->{SUBJECT_ALT_NAME} =~
/,\s*email\s*:\s*([^,]*),?/ );
}
} elsif ($ret->{HEADER}->{SUBJECT} and
$ret->{SUBJECT_HASH}->{EMAILADDRESS} and
$ret->{SUBJECT_HASH}->{EMAILADDRESS}[0]) {
$ret->{EMAILADDRESS} = $ret->{SUBJECT_HASH}->{EMAILADDRESS}[0];
} else {
$ret->{EMAILADDRESS} = $ret->{DN_HASH}->{EMAILADDRESS}[0];
}
if ($self->{DEBUG}) {
print "OpenCA::REQ->parseReq: SUBJECT_ALT_NAME:
".$ret->{HEADER}->{SUBJECT_ALT_NAME}."<br>\n";
print "OpenCA::REQ->parseReq: EMAILADDRESS:
".$ret->{EMAILADDRESS}."<br>\n";
}
if ($ret->{HEADER}->{TYPE} !~ /HEADER/) {
## Common Request Parsing ...
( $ret->{PK_ALGORITHM})=($textReq =~ /Public Key Algorithm:
([^\n]+)/i);
( $ret->{EXPONENT} ) = ( $textReq =~ /Exponent: ([\d]+)/i );
( $ret->{KEYSIZE} ) = ( $textReq =~ /Modulus[\s]*\(([\d]+)/gi );
( $ret->{SIG_ALGORITHM})=($textReq =~ /Signature Algorithm: (.*?)\n/
);
$ret->{TYPE} .= " with PKCS#7 Signature" if ( $ret->{SIGNATURE} );
}
return $ret;
}
sub getTXT {
my $self = shift;
my $ret;
if( $self->{reqFormat} =~ /SPKAC/i ) {
return $self->setError (7241011, "OpenCA::REQ->getTXT: The request
should be in SPKAC-format ".
"but there is no SPKAC-request.")
if( not $self->{spkacREQ} );
$ret = $self->{req} .
$self->{backend}->SPKAC( $self->{spkacREQ} );
return $ret;
} elsif( $self->{reqFormat} =~ /CRR/i ) {
return $self->setError (7241013, "OpenCA::REQ->getTXT: The request
should be a CRR ".
"but there is no such request.")
if( not $self->{revokeREQ} );
$ret = $self->{req};
return $ret;
} else {
return $self->setError (7241015, "OpenCA::REQ->getTXT: The request
should be a TXT-request ".
"but there is no TXT-request.")
if ( not $self->{txtREQ} );
return $self->{txtREQ};
}
}
sub getPEM {
my $self = shift;
my $ret;
return $self->setError (7242011, "OpenCA::REQ->getPEM: The request is in
SPKAC-format and not in PEM-format.")
if( $self->{reqFormat} =~ /SPKAC/i );
return $self->setError (7242013, "OpenCA::REQ->getPEM: The request is a CRR.")
if( $self->{reqFormat} =~ /CRR/i );
return $self->setError (7242015, "OpenCA::REQ->getPEM: The request is not
available in PEM-format.")
if ( not $self->{pemREQ} );
return $self->{pemREQ};
}
sub getDER {
my $self = shift;
my $ret;
return $self->setError (7243011, "OpenCA::REQ->getDER: The request is in
SPKAC-format and not in DER-format.")
if( $self->{reqFormat} =~ /SPKAC/i );
return $self->setError (7243013, "OpenCA::REQ->getDER: The request is a CRR.")
if( $self->{reqFormat} =~ /CRR/i );
return $self->setError (7243015, "OpenCA::REQ->getDER: The request is not
available in DER-format.")
if ( not $self->{derREQ} );
return $self->{derREQ};
}
sub getItem {
my $self = shift;
return $self->getParsed()->{ITEM};
}
sub getSerial {
my $self = shift;
my $ret = $self->getParsed()->{HEADER}->{SERIAL};
if (not defined $ret) {
## old requests
$ret = $self->getParsed()->{SERIAL};
}
return $ret;
}
# Autoload methods go after =cut, and are processed by the autosplit program.
1;
__END__
# Below is the stub of documentation for your module. You better edit it!
=head1 NAME
OpenCA::REQ - Perl extension to easily manage Cert REQUESTs
=head1 SYNOPSIS
use OpenCA::REQ;
=head1 DESCRIPTION
Sorry, no help available. The REQ module is capable of importing
request like this:
-----BEGIN HEADER-----
VAR = NAME
VAR = NAME
...
-----END HEADER-----
(real request text here)
-----BEGIN PKCS7-----
(pkcs#7 signature here
-----END PKCS7-----
The Real request text can be a request in every form ( DER|PEM ) or
textual (called SPKAC|CRR datatype). The syntax of the latters
is VAR = NAME on each line (just like the HEADER section).
=head1 AUTHOR
Massimiliano Pala <[EMAIL PROTECTED]>
=head1 SEE ALSO
OpenCA::OpenSSL, OpenCA::X509, OpenCA::CRL, OpenCA::Configuration,
OpenCA::TRIStateCGI, OpenCA::Tools
=cut
## OpenCA::REQ
##
## Copyright (C) 1998-1999 Massimiliano Pala ([EMAIL PROTECTED])
## All rights reserved.
##
## This library is free for commercial and non-commercial use as long as
## the following conditions are aheared to. The following conditions
## apply to all code found in this distribution, be it the RC4, RSA,
## lhash, DES, etc., code; not just the SSL code. The documentation
## included with this distribution is covered by the same copyright terms
##
## Copyright remains Massimiliano Pala's, and as such any Copyright notices
## in the code are not to be removed.
## If this package is used in a product, Massimiliano Pala should be given
## attribution as the author of the parts of the library used.
## This can be in the form of a textual message at program startup or
## in documentation (online or textual) provided with the package.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
## are met:
## 1. Redistributions of source code must retain the copyright
## notice, this list of conditions and the following disclaimer.
## 2. Redistributions in binary form must reproduce the above copyright
## notice, this list of conditions and the following disclaimer in the
## documentation and/or other materials provided with the distribution.
## 3. All advertising materials mentioning features or use of this software
## must display the following acknowledgement:
## "This product includes OpenCA software written by Massimiliano Pala
## ([EMAIL PROTECTED]) and the OpenCA Group (www.openca.org)"
## 4. If you include any Windows specific code (or a derivative thereof) from
## some directory (application code) you must include an acknowledgement:
## "This product includes OpenCA software (www.openca.org)"
##
## THIS SOFTWARE IS PROVIDED BY OPENCA DEVELOPERS ``AS IS'' AND
## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
## OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
## OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
## SUCH DAMAGE.
##
## The licence and distribution terms for any publically available version or
## derivative of this code cannot be changed. i.e. this code cannot simply be
## copied and put under another distribution licence
## [including the GNU Public Licence.]
##
## moduleerrorcode is 72
##
## functions:
##
## new 11
## initReq 12
## getParsed 21
## getHeader 31
## getSignature 32
## getKey 33
## getBody 34
## getRawHeader 35
## parseReq 13
## getTXT 41
## getPEM 42
## getDER 43
## getItem 51
## getSerial 52
use strict;
use Digest::MD5;
use X500::DN;
package OpenCA::REQ;
our ($errno, $errval);
($OpenCA::REQ::VERSION = '$Revision: 1.36 $' )=~ s/(?:^.*: (\d+))|(?:\s+\$$)/defined
$1?"0\.9":""/eg;
my %params = (
req => undef,
item => undef,
pemREQ => undef,
derREQ => undef,
txtREQ => undef,
spkacREQ => undef,
revokeREQ => undef,
parsedSPKAC => undef,
parsedCRR => undef,
parsedItem => undef,
backend => undef,
beginHeader => undef,
endHeader => undef,
beginSignature => undef,
endSignature => undef,
beginKey => undef,
endKey => undef,
reqFormat => undef,
);
sub setError {
my $self = shift;
if (scalar (@_) == 4) {
my $keys = { @_ };
$errval = $keys->{ERRVAL};
$errno = $keys->{ERRNO};
} else {
$errno = $_[0];
$errval = $_[1];
}
## support for: return $self->setError (1234, "Something fails.") if (not
$xyz);
return undef;
}
sub new {
my $that = shift;
my $class = ref($that) || $that;
my $self = {
%params,
};
bless $self, $class;
$self->{beginHeader} = "-----BEGIN HEADER-----";
$self->{endHeader} = "-----END HEADER-----";
$self->{beginSignature} = "-----BEGIN PKCS7-----";
$self->{endSignature} = "-----END PKCS7-----";
$self->{beginKey} = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
$self->{endKey} = "-----END ENCRYPTED PRIVATE KEY-----";
$self->{reqFormat} = "";
my $keys = { @_ };
my ( $infile, $keyfile, $tmp );
$self->{req} = $keys->{DATA};
$self->{reqFormat} = ( $keys->{FORMAT} or $keys->{INFORM} );
$self->{backend} = $keys->{SHELL};
$infile = $keys->{INFILE};
$keyfile = $keys->{KEYFILE};
return $self->setError (7211011, "OpenCA::REQ->new: The backend is not
specified.") if (not $self->{backend});
if( $keyfile ) {
if ( not defined $self->{reqFormat} or not $self->{reqFormat} ) {
$self->{reqFormat} = "PEM";
}
$self->{req} = $self->{backend}->genReq( KEYFILE=>$keys->{KEYFILE},
DN=>$keys->{DN},
SUBJECT=>$keys->{SUBJECT},
OUTFORM=>$self->{reqFormat},
PASSWD=>$keys->{PASSWD} );
return $self->setError (7211021,
"OpenCA::REQ->new: Cannot create new request.\n".
"Backend fails with errorcode ".$OpenCA::OpenSSL::errno."\n".
$OpenCA::OpenSSL::errval)
if ( not $self->{req} );
}
if( $infile ) {
$self->{req} = "";
open(FD, "<$infile" ) or
return $self->setError (7211031,
"OpenCA::REQ->new: Cannot open infile
$infile for reading.");
while ( $tmp = <FD> ) {
$self->{req} .= $tmp;
}
close(FD);
return $self->setError (7211033, "Cannot read request from infile
$infile.")
if( not $self->{req});
}
if( not (defined($self->{reqFormat})) or ($self->{reqFormat} eq "")) {
if( ( $self->{req} ) and ( $self->{req} =~ /SPKAC\s*=\s*/g ) ){
$self->{reqFormat} = "SPKAC";
} elsif (($self->{req}) and ($self->{req} =~
/REVOKE_CERTIFICATE_SERIAL\s*=\s*/g)){
$self->{reqFormat} = "CRR";
} else {
$self->{reqFormat} = "PEM";
}
}
if ( $self->{req} ne "" ) {
$self->{item} = $self->{req};
if ( not $self->initReq( REQ=>$self->{req},
FORMAT=>$self->{reqFormat})) {
return $self->setError (7211041,
"OpenCA::REQ->new: Cannot initialize request
(".$errno.")\n".$errval);
}
}
return $self;
}
sub initReq {
my $self = shift;
my $keys = { @_ };
$self->{reqFormat} = $keys->{FORMAT};
$self->{req} = $self->getBody( REQUEST=> $keys->{REQ});
if (not $self->{req}) {
$self->{parsedItem} = $self->parseReq( REQ=>$keys->{REQ},
FORMAT=>$self->{reqFormat} );
return $self->setError (7212011, "OpenCA::REQ->initReq: Cannot parse
request ".
"($errno):\n$errval")
if (not $self->{parsedItem});
} elsif( $self->{reqFormat} !~ /SPKAC|CRR/i ) {
$self->{pemREQ} = $self->{backend}->dataConvert(
DATA=>$self->{req},
DATATYPE=>"REQUEST",
INFORM=>$self->{reqFormat},
OUTFORM=>"PEM" );
return $self->setError (7212021, "OpenCA::REQ->initReq: Cannot convert
request to PEM-format ".
"(".$OpenCA::OpenSSL::errno."):\n".
$OpenCA::OpenSSL::errval)
if (not $self->{pemREQ});
$self->{derREQ} = $self->{backend}->dataConvert(
DATA=>$self->{req},
DATATYPE=>"REQUEST",
INFORM=>$self->{reqFormat},
OUTFORM=>"DER" );
return $self->setError (7212022, "OpenCA::REQ->initReq: Cannot convert
request to DER-format ".
"(".$OpenCA::OpenSSL::errno."):\n".
$OpenCA::OpenSSL::errval)
if (not $self->{derREQ});
$self->{txtREQ} = $self->{backend}->dataConvert(
DATA=>$self->{req},
DATATYPE=>"REQUEST",
INFORM=>$self->{reqFormat},
OUTFORM=>"TXT" );
return $self->setError (7212023, "OpenCA::REQ->initReq: Cannot convert
request to TXT-format ".
"(".$OpenCA::OpenSSL::errno."):\n".
$OpenCA::OpenSSL::errval)
if (not $self->{txtREQ});
$self->{parsedItem} = $self->parseReq( REQ=>$keys->{REQ},
FORMAT=>$self->{reqFormat} );
return $self->setError (7212024, "OpenCA::REQ->initReq: Cannot parse
request ".
"($errno):\n$errval")
if (not $self->{parsedItem});
} else {
if ( $self->{reqFormat} =~ /SPKAC/ ) {
$self->{spkacREQ} = $self->{req};
$self->{parsedSPKAC}=$self->parseReq( REQ=>$keys->{REQ},
FORMAT=>"SPKAC" );
$self->{parsedItem} = $self->{parsedSPKAC};
return $self->setError (7212026, "OpenCA::REQ->initReq: Cannot
parse request ".
"($errno):\n$errval")
if( not $self->{parsedSPKAC} );
} elsif ( $self->{reqFormat} =~ /CRR/ ) {
$self->{revokeREQ} = $self->{req};
$self->{parsedCRR}=
$self->parseReq( REQ=>$keys->{REQ},
FORMAT=>"CRR" );
$self->{parsedItem} = $self->{parsedCRR};
return $self->setError (7212031, "OpenCA::REQ->initReq: Cannot
parse request ".
"($errno):\n$errval")
if( not $self->{parsedCRR} );
} else {
return $self->setError (7212041, "OpenCA::REQ->initReq:
Unknown request's format.");
}
}
return 1;
}
sub getParsed {
my $self = shift;
if( $self->{reqFormat} =~ /SPKAC/i ) {
return $self->setError (7221011, "OpenCA::REQ->getParsed:
SPKAC-request was not parsed.")
if( not $self->{parsedSPKAC} );
return $self->{parsedSPKAC};
} elsif( $self->{reqFormat} =~ /CRR/i ) {
return $self->setError (7221013, "OpenCA::REQ->getParsed: CRR was not
parsed.")
if( not $self->{parsedCRR} );
return $self->{parsedCRR};
} else {
return $self->setError (7221014, "OpenCA::REQ->getParsed: Request was
not parsed.")
if ( not $self->{parsedItem} );
return $self->{parsedItem};
}
}
sub getHeader {
my $self = shift;
my $keys = { @_ };
my $req = $keys->{REQUEST};
my ( $txt, $ret, $i, $key, $val );
my $beginHeader = $self->{beginHeader};
my $endHeader = $self->{endHeader};
if( ($txt) = ( $req =~ /$beginHeader\s*\n([\s\S\n]+)\n$endHeader/) ) {
foreach $i ( split ( /\s*\n/, $txt ) ) {
## fix CR
$i =~ s/\s*\r$//;
$i =~ s/\s*=\s*/=/;
( $key, $val ) = ( $i =~ /^([^=]*)\s*=\s*(.*)\s*/ );
$ret->{$key} = $val;
## fix old requests
if ($key eq "SUBJ") {
$ret->{SUBJECT} = $val;
}
}
}
return $ret;
}
sub getRawHeader {
my $self = shift;
my $keys = { @_ };
my $req = $keys->{REQUEST};
my $beginHeader = $self->{beginHeader};
my $endHeader = $self->{endHeader};
my ( $ret ) = ( $req =~ /($beginHeader[\S\s\n]+$endHeader)/ );
return $ret;
}
sub getSignature {
my $self = shift;
my $keys = { @_ };
my $req = $keys->{REQUEST};
my $beginSig = $self->{beginSignature};
my $endSig = $self->{endSignature};
my ( $ret ) = ( $req =~ /($beginSig[\S\s\n]+$endSig)/ );
return $ret;
}
sub getKey {
my $self = shift;
my $keys = { @_ };
my $req = $keys->{REQUEST};
my $beginKey = $self->{beginKey};
my $endKey = $self->{endKey};
my ( $ret ) = ( $req =~ /($beginKey[\S\s\n]+$endKey)/ );
return $ret;
}
sub getBody {
my $self = shift;
my $keys = { @_ };
my $ret = $keys->{REQUEST};
my $beginHeader = $self->{beginHeader};
my $endHeader = $self->{endHeader};
my $beginSig = $self->{beginSignature};
my $endSig = $self->{endSignature};
my $beginKey = $self->{beginKey};
my $endKey = $self->{endKey};
## Let's throw away text between the two headers, included
$ret =~ s/($beginHeader[\S\s\n]+$endHeader\n*)//;
## Let's throw away text between the two headers, included
$ret =~ s/($beginSig[\S\s\n]+$endSig)//;
## Let's throw away text between the two headers, included
$ret =~ s/($beginKey[\S\s\n]+$endKey)//;
$ret =~ s/\n$//;
return $ret;
}
sub parseReq {
my $self = shift;
my $keys = { @_ };
my $fullReq = $keys->{REQ};
my $format = $keys->{FORMAT};
my @dnList = ();
my @exts = ();
my ( $ret, $tmp, $key, $val, $tmpOU, $ra, $textReq );
return $self->setError (7213011, "There is no complete request available.")
if (not $fullReq);
$ret->{SIGNATURE} = $self->getSignature ( REQUEST=>$fullReq );
$ret->{KEY} = $self->getKey ( REQUEST=>$fullReq );
$ret->{HEADER} = $self->getHeader ( REQUEST=>$fullReq );
$ret->{RAWHEADER} = $self->getRawHeader ( REQUEST=>$fullReq );
$ret->{BODY} = $self->getBody ( REQUEST=> $fullReq);
$ret->{ITEM} = $self->{item};
if (not $ret->{BODY}) {
## this must be a request with TYPE == HEADER
print "OpenCA::REQ->parseReq: This is a HEADER only.<br>\n" if
($self->{DEBUG});
if ( not $ret->{HEADER} ) {
return $self->setError (7213015,
"OpenCA::REQ->initReq: The request has no body.");
}
if ( not $ret->{HEADER}->{TYPE} =~ /HEADER/i ) {
return $self->setError (7213016,
"OpenCA::REQ->initReq: The request has no body and has
not the type HEADER.");
}
$ret->{TYPE} = "HEADER";
$ret->{DN} = $ret->{HEADER}->{SUBJECT};
} else {
$textReq = $ret->{BODY};
print "OpenCA::REQ->parseReq: FORMAT: $format<br>\n" if
($self->{DEBUG});
if ( $format !~ /CRR/ ) {
## Get Attributes from openssl directly
my @attrlist;
if ( $format =~ /SPKAC/i ) {
@attrlist = ( "PUBKEY" );
} else {
@attrlist = ( "PUBKEY", "DN" );
}
my $attrs = $self->{backend}->getReqAttribute(
DATA=>$ret->{BODY}. "\n",
ATTRIBUTE_LIST=>\@attrlist,
FORMAT=>$format );
foreach (keys %$attrs ) {
$ret->{$_} = $attrs->{$_};
if ($self->{DEBUG}) {
print "OpenCA::REQ->parseReq: ATTRIBUTE:
".$_."<br>\n";
print "OpenCA::REQ->parseReq: VALUE:
".$ret->{$_}."<br>\n";
}
}
}
if( exists $ret->{PUBKEY} ) {
my $md5 = new Digest::MD5;
$md5->add( $ret->{PUBKEY} );
$ret->{KEY_DIGEST} = $md5->hexdigest();
}
if ( $format =~ /SPKAC/i ) {
## Specific for SPKAC requests...
my ( @reqLines );
@reqLines = split( /\n/ , $textReq );
for $tmp (@reqLines) {
$tmp =~ s/\r$//;
my ($key,$val)=($tmp =~ /([\w]+)\s*=\s*(.*)\s*/ );
$key = uc( $key );
if ($key ne "") {
if ($key =~ /SPKAC/i) {
$ret->{SPKAC} = $val;
} else {
$ret->{DN} .= ", " if ($ret->{DN});
$ret->{DN} .= $key."=".$val;
}
}
}
## Now retrieve the SPKAC crypto infos...
$textReq=$self->{backend}->SPKAC( SPKAC=>$ret->{BODY});
$ret->{VERSION} = 1;
$ret->{TYPE} = 'SPKAC';
} elsif( $format =~ /CRR/i ) {
## Specific for SPKAC requests...
my ( @reqLines );
@reqLines = split( /\n/ , $textReq );
for $tmp (@reqLines) {
$tmp =~ s/\r$//;
($key,$val)=($tmp =~ /([\w]+)\s*=\s*(.*)\s*/ );
$key = uc( $key );
$ret->{$key} = $val;
}
$ret->{VERSION} = 1 if ( not exists $ret->{VERSION});
$ret->{TYPE} = 'CRR';
$ret->{HEADER}->{TYPE} = $ret->{TYPE};
$ret->{REVOKE_CERTIFICATE_DN} =~ s/^\///;
$ret->{REVOKE_CERTIFICATE_DN} =~ s/\/([^=]+)=/, $1=/g;
## allow automatic parsing
$ret->{DN} = $ret->{REVOKE_CERTIFICATE_DN};
} else {
$textReq = $self->{backend}->dataConvert( DATA=>$textReq,
DATATYPE=>"REQUEST", INFORM=>$format, OUTFORM=>"TXT");
return $self->setError (7213021, "OpenCA::REQ->parseReq:
Cannot convert request to text-format ".
"(".$OpenCA::OpenSSL::errno.")\n".$OpenCA::OpenSSL::errval)
if ( not $textReq );
## Specific for NON SPKAC requests ...
# ( $ret->{VERSION} ) = ( $textReq =~ /Version:\s+([a-f\d]+)/i
);
( $ret->{VERSION} ) = ( $textReq =~
/Version:\s+([[:xdigit:]]+\s(\([[:xdigit:]]+x[[:xdigit:]]+\))?)/i );
$ret->{DN} =~ s/\,\s*$//;
## We do not verify signature, here...
## $ret->{VERSION} = 0;
if( exists $ret->{HEADER}->{TYPE} ) {
$ret->{TYPE} = $ret->{HEADER}->{TYPE};
} else {
$ret->{TYPE} = 'PKCS#10';
}
}
}
## load the differnt parts of the DN into DN_HASH
my $x500_dn = X500::DN->ParseRFC2253 ($ret->{DN});
my $rdn;
foreach $rdn ($x500_dn->getRDNs()) {
next if ($rdn->isMultivalued());
my @attr_types = $rdn->getAttributeTypes();
my $type = $attr_types[0];
my $value = $rdn->getAttributeValue ($type);
push (@{$ret->{DN_HASH}->{uc($type)}}, $value);
print "OpenCA::REQ->parseReq: DN_HASH: $type=$value<br>\n" if
($self->{DEBUG});
}
## load the differnt parts of the DN into DN_HASH
if ($ret->{HEADER}->{SUBJECT}) {
my $x500_dn = X500::DN->ParseRFC2253 ($ret->{HEADER}->{SUBJECT});
my $rdn;
foreach $rdn ($x500_dn->getRDNs()) {
next if ($rdn->isMultivalued());
my @attr_types = $rdn->getAttributeTypes();
my $type = $attr_types[0];
my $value = $rdn->getAttributeValue ($type);
push (@{$ret->{SUBJECT_HASH}->{uc($type)}}, $value);
print "OpenCA::REQ->parseReq: DN_HASH: $type=$value<br>\n" if
($self->{DEBUG});
}
}
## show DN to check conformance to RFC 2253
if ($self->{DEBUG}) {
print "OpenCA::REQ->parseReq: TYPE: ".$ret->{TYPE}."<br>\n";
print "OpenCA::REQ->parseReq: DN: ".$ret->{DN}."<br>\n";
}
## set emailaddress
## FIXME: actually we ignore the subject alternative name in the header
## FIXME: this is a BUG
if ($ret->{HEADER}->{SUBJECT_ALT_NAME} and
( ($ret->{HEADER}->{SUBJECT_ALT_NAME} =~ /^\s*email\s*:/i) or
($ret->{HEADER}->{SUBJECT_ALT_NAME} =~ /,\s*email\s*:/i) ) ) {
( $ret->{EMAILADDRESS} ) =
( $ret->{HEADER}->{SUBJECT_ALT_NAME} =~
/^\s*email\s*:\s*([^,]*),?/ );
if (not $ret->{EMAILADDRESS}) {
( $ret->{EMAILADDRESS} ) =
( $ret->{HEADER}->{SUBJECT_ALT_NAME} =~
/,\s*email\s*:\s*([^,]*),?/ );
}
} elsif ($ret->{HEADER}->{SUBJECT} and
$ret->{SUBJECT_HASH}->{EMAILADDRESS} and
$ret->{SUBJECT_HASH}->{EMAILADDRESS}[0]) {
$ret->{EMAILADDRESS} = $ret->{SUBJECT_HASH}->{EMAILADDRESS}[0];
} else {
$ret->{EMAILADDRESS} = $ret->{DN_HASH}->{EMAILADDRESS}[0];
}
if ($self->{DEBUG}) {
print "OpenCA::REQ->parseReq: SUBJECT_ALT_NAME:
".$ret->{HEADER}->{SUBJECT_ALT_NAME}."<br>\n";
print "OpenCA::REQ->parseReq: EMAILADDRESS:
".$ret->{EMAILADDRESS}."<br>\n";
}
if ($ret->{HEADER}->{TYPE} !~ /HEADER/) {
## Common Request Parsing ...
( $ret->{PK_ALGORITHM})=($textReq =~ /Public Key Algorithm:
([^\n]+)/i);
( $ret->{EXPONENT} ) = ( $textReq =~ /Exponent: ([\d]+)/i );
( $ret->{KEYSIZE} ) = ( $textReq =~ /Modulus[\s]*\(([\d]+)/gi );
( $ret->{SIG_ALGORITHM})=($textReq =~ /Signature Algorithm: (.*?)\n/
);
$ret->{TYPE} .= " with PKCS#7 Signature" if ( $ret->{SIGNATURE} );
}
return $ret;
}
sub getTXT {
my $self = shift;
my $ret;
if( $self->{reqFormat} =~ /SPKAC/i ) {
return $self->setError (7241011, "OpenCA::REQ->getTXT: The request
should be in SPKAC-format ".
"but there is no SPKAC-request.")
if( not $self->{spkacREQ} );
$ret = $self->{req} .
$self->{backend}->SPKAC( $self->{spkacREQ} );
return $ret;
} elsif( $self->{reqFormat} =~ /CRR/i ) {
return $self->setError (7241013, "OpenCA::REQ->getTXT: The request
should be a CRR ".
"but there is no such request.")
if( not $self->{revokeREQ} );
$ret = $self->{req};
return $ret;
} else {
return $self->setError (7241015, "OpenCA::REQ->getTXT: The request
should be a TXT-request ".
"but there is no TXT-request.")
if ( not $self->{txtREQ} );
return $self->{txtREQ};
}
}
sub getPEM {
my $self = shift;
my $ret;
return $self->setError (7242011, "OpenCA::REQ->getPEM: The request is in
SPKAC-format and not in PEM-format.")
if( $self->{reqFormat} =~ /SPKAC/i );
return $self->setError (7242013, "OpenCA::REQ->getPEM: The request is a CRR.")
if( $self->{reqFormat} =~ /CRR/i );
return $self->setError (7242015, "OpenCA::REQ->getPEM: The request is not
available in PEM-format.")
if ( not $self->{pemREQ} );
return $self->{pemREQ};
}
sub getDER {
my $self = shift;
my $ret;
return $self->setError (7243011, "OpenCA::REQ->getDER: The request is in
SPKAC-format and not in DER-format.")
if( $self->{reqFormat} =~ /SPKAC/i );
return $self->setError (7243013, "OpenCA::REQ->getDER: The request is a CRR.")
if( $self->{reqFormat} =~ /CRR/i );
return $self->setError (7243015, "OpenCA::REQ->getDER: The request is not
available in DER-format.")
if ( not $self->{derREQ} );
return $self->{derREQ};
}
sub getItem {
my $self = shift;
return $self->getParsed()->{ITEM};
}
sub getSerial {
my $self = shift;
my $ret = $self->getParsed()->{HEADER}->{SERIAL};
if (not defined $ret) {
## old requests
$ret = $self->getParsed()->{SERIAL};
}
return $ret;
}
# Autoload methods go after =cut, and are processed by the autosplit program.
1;
__END__
# Below is the stub of documentation for your module. You better edit it!
=head1 NAME
OpenCA::REQ - Perl extension to easily manage Cert REQUESTs
=head1 SYNOPSIS
use OpenCA::REQ;
=head1 DESCRIPTION
Sorry, no help available. The REQ module is capable of importing
request like this:
-----BEGIN HEADER-----
VAR = NAME
VAR = NAME
...
-----END HEADER-----
(real request text here)
-----BEGIN PKCS7-----
(pkcs#7 signature here
-----END PKCS7-----
The Real request text can be a request in every form ( DER|PEM ) or
textual (called SPKAC|CRR datatype). The syntax of the latters
is VAR = NAME on each line (just like the HEADER section).
=head1 AUTHOR
Massimiliano Pala <[EMAIL PROTECTED]>
=head1 SEE ALSO
OpenCA::OpenSSL, OpenCA::X509, OpenCA::CRL, OpenCA::Configuration,
OpenCA::TRIStateCGI, OpenCA::Tools
=cut