File Coverage

blib/lib/OpenCA/X509.pm
Criterion Covered Total %
statement 9 270 3.3
branch 0 106 0.0
condition 0 30 0.0
subroutine 3 19 15.7
pod 0 16 0.0
total 12 441 2.7


line stmt bran cond sub pod time code
1             ## OpenCA::X509
2             ##
3             ## Copyright (C) 1998-1999 Massimiliano Pala (madwolf@openca.org)
4             ## All rights reserved.
5             ##
6             ## This library is free for commercial and non-commercial use as long as
7             ## the following conditions are aheared to. The following conditions
8             ## apply to all code found in this distribution, be it the RC4, RSA,
9             ## lhash, DES, etc., code; not just the SSL code. The documentation
10             ## included with this distribution is covered by the same copyright terms
11             ##
12             ## Copyright remains Massimiliano Pala's, and as such any Copyright notices
13             ## in the code are not to be removed.
14             ## If this package is used in a product, Massimiliano Pala should be given
15             ## attribution as the author of the parts of the library used.
16             ## This can be in the form of a textual message at program startup or
17             ## in documentation (online or textual) provided with the package.
18             ##
19             ## Redistribution and use in source and binary forms, with or without
20             ## modification, are permitted provided that the following conditions
21             ## are met:
22             ## 1. Redistributions of source code must retain the copyright
23             ## notice, this list of conditions and the following disclaimer.
24             ## 2. Redistributions in binary form must reproduce the above copyright
25             ## notice, this list of conditions and the following disclaimer in the
26             ## documentation and/or other materials provided with the distribution.
27             ## 3. All advertising materials mentioning features or use of this software
28             ## must display the following acknowledgement:
29             ## "This product includes OpenCA software written by Massimiliano Pala
30             ## (madwolf@openca.org) and the OpenCA Group (www.openca.org)"
31             ## 4. If you include any Windows specific code (or a derivative thereof) from
32             ## some directory (application code) you must include an acknowledgement:
33             ## "This product includes OpenCA software (www.openca.org)"
34             ##
35             ## THIS SOFTWARE IS PROVIDED BY OPENCA DEVELOPERS ``AS IS'' AND
36             ## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37             ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
38             ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
39             ## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
40             ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
41             ## OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
42             ## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
43             ## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44             ## OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45             ## SUCH DAMAGE.
46             ##
47             ## The licence and distribution terms for any publically available version or
48             ## derivative of this code cannot be changed. i.e. this code cannot simply be
49             ## copied and put under another distribution licence
50             ## [including the GNU Public Licence.]
51             ##
52              
53             ## the module's errorcode is 74
54             ##
55             ## functions
56             ##
57             ## new 11
58             ## init 12
59             ## getHeader 21
60             ## getKey 22
61             ## getBody 23
62             ## getParsed 31
63             ## parseCert 13
64             ## getPEM 41
65             ## getPEMHeader 42
66             ## getDER 43
67             ## getTXT 44
68             ## setHeaderAttribute 51
69             ## getItem 61
70             ## getSerial 62
71             ## setParams 71
72              
73 1     1   1212 use strict;
  1         2  
  1         40  
74 1     1   5 use Digest::MD5;
  1         1  
  1         37  
75 1     1   784 use X500::DN;
  1         241046  
  1         6143  
76              
77             package OpenCA::X509;
78              
79             our ($errno, $errval);
80              
81             ($OpenCA::X509::VERSION = '$Revision: 1.47 $' )=~ s/(?:^.*: (\d+))|(?:\s+\$$)/defined $1?"0\.9":""/eg;
82              
83             my %params = (
84             cert => undef,
85             item => undef,
86             pemCert => undef,
87             pemHeader => undef,
88             derCert => undef,
89             txtCert => undef,
90             backend => undef,
91             parsedItem => undef,
92             beginCert => undef,
93             endCert => undef,
94             beginHeader => undef,
95             endHeader => undef,
96             beginKey => undef,
97             endKey => undef,
98             beginAttribute => undef,
99             endAttribute => undef,
100             certFormat => undef,
101             );
102              
103             sub setError {
104 0     0 0   my $self = shift;
105              
106 0 0         if (scalar (@_) == 4) {
107 0           my $keys = { @_ };
108 0           $errval = $keys->{ERRVAL};
109 0           $errno = $keys->{ERRNO};
110             } else {
111 0           $errno = $_[0];
112 0           $errval = $_[1];
113             }
114              
115             ## support for: return $self->setError (1234, "Something fails.") if (not $xyz);
116 0           return undef;
117             }
118              
119             ## Create an instance of the Class
120             sub new {
121 0     0 0   my $that = shift;
122 0   0       my $class = ref($that) || $that;
123              
124 0           my $self = {
125             %params,
126             };
127              
128 0           bless $self, $class;
129              
130 0           my $keys = { @_ };
131 0           my ( $infile, $tmp );
132              
133 0           $self->{item} = $keys->{DATA};
134 0   0       $self->{certFormat} = ( $keys->{FORMAT} or $keys->{INFORM} or "PEM" );
135 0           $infile = $keys->{INFILE};
136              
137 0           $self->{backend} = $keys->{SHELL};
138              
139 0           $self->{beginCert} = "-----BEGIN CERTIFICATE-----";
140 0           $self->{endCert} = "-----END CERTIFICATE-----";
141 0           $self->{beginHeader} = "-----BEGIN HEADER-----";
142 0           $self->{endHeader} = "-----END HEADER-----";
143 0           $self->{beginAttribute} = "-----BEGIN ATTRIBUTE-----";
144 0           $self->{endAttribute} = "-----END ATTRIBUTE-----";
145 0           $self->{beginKey} = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
146 0           $self->{endKey} = "-----END ENCRYPTED PRIVATE KEY-----";
147              
148 0 0         if( $infile ) {
149 0           $self->{item} = "";
150              
151 0 0         open( FD, "<$infile" )
152             or return $self->setError (7411011, "OpenCA::X509->new: Cannot open infile $infile for reading.");
153 0           while ( $tmp = ) {
154 0           $self->{item} .= $tmp;
155             }
156 0           close( FD );
157             }
158              
159 0 0 0       if ( defined($self->{item}) and $self->{item} ne "" ) {
160 0           $self->{cert} = $self->getBody( ITEM=>$self->{item} );
161              
162 0 0         if ( not $self->init() ) {
163 0           return $self->setError (7411021, "OpenCA::X509->new: Cannot initialize certificate ".
164             "($errno)\n$errval");
165             }
166              
167             }
168              
169 0           return $self;
170             }
171              
172             sub init {
173 0     0 0   my $self = shift;
174              
175 0 0         return $self->setError (7412011, "OpenCA::X509->init: No certificate present.")
176             if (not $self->{cert});
177              
178 0           $self->{pemCert} = "";
179              
180 0           $self->{derCert} = "";
181              
182 0           $self->{txtCert} = "";
183              
184 0           $self->{parsedItem} = $self->parseCert();
185 0 0         return $self->setError (7412031, "OpenCA::X509->init: Cannot parse certificate ($errno).\n$errval")
186             if (not $self->{parsedItem});
187              
188             ## build pem-header
189 0           $self->{pemHeader} = $self->{beginHeader};
190 0           for my $h (keys %{$self->{parsedItem}->{HEADER}}) {
  0            
191 0           $self->{pemHeader} .= "\n".$h."=";
192 0 0         if ( $self->{parsedItem}->{HEADER}->{$h} =~ /\n/ ) {
193             ## multirow attribute
194 0           $self->{pemHeader} .= "\n".$self->{beginAttribute}.
195             "\n".$self->{parsedItem}->{HEADER}->{$h}.
196             "\n".$self->{endAttribute};
197             } else {
198 0           $self->{pemHeader} .= $self->{parsedItem}->{HEADER}->{$h};
199             }
200             }
201 0           $self->{pemHeader} .= "\n".$self->{endHeader}."\n";
202              
203 0           return 1;
204             }
205              
206             ## modified by michael bell to support multirow-values
207             sub getHeader {
208 0     0 0   my $self = shift;
209 0           my $keys = { @_ };
210 0           my $req = $keys->{ITEM};
211              
212 0           my ( $txt, $ret, $i, $key, $val );
213              
214 0           my $beginHeader = $self->{beginHeader};
215 0           my $endHeader = $self->{endHeader};
216 0           my $beginAttribute = $self->{beginAttribute};
217 0           my $endAttribute = $self->{endAttribute};
218              
219 0 0         if( ($txt) = ( $req =~ /$beginHeader\n([\S\s\n]+)\n$endHeader/m) ) {
220 0           my $active_multirow = 0;
221 0           foreach $i ( split ( /\n/, $txt ) ) {
222 0 0         if ($active_multirow) {
    0          
223             ## multirow
224 0 0         if ($i =~ /^$endAttribute$/) {
225             ## end of multirow
226 0           $active_multirow = 0;
227             } else {
228 0 0         $ret->{$key} .= "\n" if ($ret->{$key});
229             ## additional data
230 0           $ret->{$key} .= $i;
231             }
232             } elsif ($i =~ /^$beginAttribute$/) {
233             ## begin of multirow
234 0           $active_multirow = 1;
235             } else {
236             ## no multirow
237             ## if multirow then $ret->{key} is initially empty)
238 0           $i =~ s/\s*=\s*/=/;
239 0           ( $key, $val ) = ( $i =~ /(.*)\s*=\s*(.*)\s*/ );
240 0           $ret->{$key} = $val;
241             }
242             }
243             }
244              
245 0 0         if (not defined $ret->{CSR_SERIAL})
246             {
247 0           $ret->{CSR_SERIAL} = -1;
248             }
249              
250 0           return $ret;
251             }
252              
253             sub getKey {
254 0     0 0   my $self = shift;
255 0           my $keys = { @_ };
256 0           my $req = $keys->{ITEM};
257              
258 0           my $beginKey = $self->{beginKey};
259 0           my $endKey = $self->{endKey};
260              
261 0           my ( $ret ) = ( $req =~ /($beginKey[\S\s\n]+$endKey)/ );
262 0           return $ret;
263             }
264              
265             sub getBody {
266 0     0 0   my $self = shift;
267 0           my $keys = { @_ };
268 0           my $req = $keys->{ITEM};
269              
270 0           my $beginCert = $self->{beginCert};
271 0           my $endCert = $self->{endCert};
272              
273 0           my ( $ret ) = ( $req =~ /($beginCert[\S\s\n]+$endCert)/ );
274 0           return $ret;
275             }
276              
277             sub getParsed {
278 0     0 0   my $self = shift;
279              
280 0 0         return $self->setError (7431011, "OpenCA::X509->getParsed: The certificate was not parsed.")
281             if ( not $self->{parsedItem} );
282 0           return $self->{parsedItem};
283             }
284              
285             sub parseCert {
286              
287 0     0 0   my $self = shift;
288 0           my $keys = { @_ };
289              
290 0           my ( @ouList, @exts, $ret, $k, $v, $tmp, $md5 );
291              
292 0           my @attList = ( "SERIAL", "DN", "ISSUER", "NOTBEFORE", "NOTAFTER",
293             "ALIAS", "MODULUS", "PUBKEY", "FINGERPRINT", "HASH", "EMAILADDRESS",
294             "VERSION", "PUBKEY_ALGORITHM", "SIGNATURE_ALGORITHM", "EXPONENT",
295             "KEYSIZE", "EXTENSIONS" );
296 0 0         if ($self->{certFormat} eq "DER")
297             {
298 0           $ret = $self->{backend}->getCertAttribute(
299             ATTRIBUTE_LIST => \@attList,
300             DATA => $self->getDER(),
301             INFORM => "DER");
302             } else {
303 0           $ret = $self->{backend}->getCertAttribute(
304             ATTRIBUTE_LIST => \@attList,
305             DATA => $self->getPEM(),
306             INFORM => "PEM");
307             }
308              
309 0 0         print "OpenCA::X509->parseCert: DN: ".$ret->{SUBJECT}."
\n" if ($self->{DEBUG});
310              
311 0           $ret->{DN} =~ s/(^\/|\/$)//g;
312 0           $ret->{DN} =~ s/\/([A-Za-z0-9\-]+)=/, $1=/g;
313            
314 0           $ret->{ISSUER} =~ s/(^\/|\/$)//g;
315 0           $ret->{ISSUER} =~ s/\/([A-Za-z0-9\-]+)=/, $1=/g;
316              
317             ## OpenSSL includes a bug in -nameopt RFC2253
318             ## = signs are not escaped if they are normal values
319 0           my $i = 0;
320 0           my $now = "name";
321 0           while ($i < length ($ret->{DN}))
322             {
323 0 0         if (substr ($ret->{DN}, $i, 1) =~ /\\/)
    0          
    0          
324             {
325 0           $i++;
326             } elsif (substr ($ret->{DN}, $i, 1) =~ /=/) {
327 0 0         if ($now =~ /value/)
328             {
329             ## OpenSSL forgets to escape =
330 0           $ret->{DN} = substr ($ret->{DN}, 0, $i)."\\".substr ($ret->{DN}, $i);
331 0           $i++;
332             } else {
333 0           $now = "value";
334             }
335             } elsif (substr ($ret->{DN}, $i, 1) =~ /[,+]/) {
336 0           $now = "name";
337             }
338 0           $i++;
339             }
340              
341             ## load the differnt parts of the DN into DN_HASH
342 0 0         print "OpenCA::X509->parseCert: DN: ".$ret->{DN}."
\n" if ($self->{DEBUG});
343 0 0         if ($ret->{DN} =~ /\\/) {
344 0           my $x500_dn = X500::DN->ParseRFC2253 ($ret->{DN});
345 0 0         if (not $x500_dn) {
346 0 0         print "OpenCA::X509->parseCert: X500::DN failed
\n" if ($self->{DEBUG});
347 0           return $self->setError (7413031, "OpenCA::X509->parseCert: X500::DN failed.");
348 0           return undef;
349             }
350 0           my $rdn;
351 0           foreach $rdn ($x500_dn->getRDNs()) {
352 0 0         next if ($rdn->isMultivalued());
353 0           my @attr_types = $rdn->getAttributeTypes();
354 0           my $type = $attr_types[0];
355 0           my $value = $rdn->getAttributeValue ($type);
356 0           push (@{$ret->{DN_HASH}->{uc($type)}}, $value);
  0            
357 0 0         print "OpenCA::X509->parseCert: DN_HASH: $type=$value
\n" if ($self->{DEBUG});
358             }
359             } else {
360 0           my @rdns = split /,/, $ret->{DN};
361 0           foreach my $rdn (@rdns) {
362 0           my ($type, $value) = split /=/, $rdn;
363 0           $type =~ s/^\s*//;
364 0           $type =~ s/\s*$//;
365 0           $value =~ s/^\s*//;
366 0           $value =~ s/\s*$//;
367 0           push (@{$ret->{DN_HASH}->{uc($type)}}, $value);
  0            
368 0 0         print "OpenCA::REQ->parseReq: DN_HASH: $type=$value
\n" if ($self->{DEBUG});
369             }
370             }
371              
372 0 0         if( exists $ret->{PUBKEY} ) {
373 0           $md5 = new Digest::MD5;
374 0           $md5->add( $ret->{PUBKEY} );
375 0           $ret->{KEY_DIGEST} = $md5->hexdigest();
376             }
377              
378             ## Check if Email field is only present in subjectAltName
379 0 0 0       if (not $ret->{EMAILADDRESS} and
      0        
380             exists $ret->{DN_HASH}->{EMAILADDRESS} and
381             $ret->{DN_HASH}->{EMAILADDRESS}[0]) {
382 0           $ret->{EMAILADDRESS} = $ret->{DN_HASH}->{EMAILADDRESS}[0];
383             }
384              
385 0           $ret->{SIG_ALGORITHM} = $ret->{SIGNATURE_ALGORITHM};
386 0           $ret->{PK_ALGORITHM} = $ret->{PUBKEY_ALGORITHM};
387              
388             ## load all extensions
389 0           $ret->{PLAIN_EXTENSIONS} = $ret->{EXTENSIONS};
390 0           delete $ret->{EXTENSIONS};
391 0           $ret->{OPENSSL_EXTENSIONS} = {};
392              
393 0           my ($c, $val, $key);
394 0           my @lines = split(/\n/, $ret->{PLAIN_EXTENSIONS});
395              
396 0           $i = 0;
397 0           while($i < @lines) {
398 0 0         if($lines[$i] =~ /^[\s\t]*[^:]+:\s*(critical|)\s*$/i) {
399 0           $key = $lines[$i];
400 0           $key =~ s/[\s\t]*:.*$//g;
401 0           $key =~ s/^[\s\t]*//g;
402 0           $ret->{OPENSSL_EXTENSIONS}->{$key} = [];
403 0           $i++;
404 0   0       while($lines[$i] !~ /^[\s\t].+:\s*$/ && $i < @lines) {
405 0           $val = $lines[$i];
406 0           $val =~ s/^[\s]+//g;
407 0           $val =~ s/[\s]+$//g;
408 0           $i++;
409 0 0         next if $val =~ /^$/;
410 0           push(@{$ret->{OPENSSL_EXTENSIONS}->{$key}}, $val);
  0            
411             }
412             } else {
413             ## FIXME: can this every happen?
414 0           $i++;
415             }
416             }
417              
418 0 0         if ($self->{DEBUG}) {
419 0           print "OpenCA::X509->parseCert: show all extensions and their values
\n";
420 0           while(($key, $val) = each(%{$ret->{OPENSSL_EXTENSIONS}})) {
  0            
421 0           print "OpenCA::X509->parseCert: found extension: $key
\n";
422 0           print "OpenCA::X509->parseCert: with value(s): $_
\n" foreach(@{$val});
  0            
423             }
424             }
425              
426             ## load special extensions
427 0           my $h = $ret->{OPENSSL_EXTENSIONS}->{"X509v3 Basic Constraints"}[0];
428 0   0       $h ||= "";
429 0           $h =~ s/\s//g;
430 0 0         if ($h =~ /CA:TRUE/i) {
431 0           $ret->{IS_CA} = 1;
432 0           $ret->{EXTENSIONS}->{BASIC_CONSTRAINTS}->{CA} = 1;
433             } else {
434 0           $ret->{IS_CA} = 0;
435 0           $ret->{EXTENSIONS}->{BASIC_CONSTRAINTS}->{CA} = 0;
436             }
437              
438 0           $ret->{BODY} = $self->getBody (ITEM => $self->{item});
439 0           $ret->{HEADER} = $self->getHeader (ITEM => $self->{item});
440 0           $ret->{KEY} = $self->getKey (ITEM => $self->{item});
441 0           $ret->{ITEM} = $ret->{BODY};
442 0           $ret->{FLAG_EXPORT_STATE} = 0;
443              
444             ## if email was not set then we check the subject alternative name
445 0 0         if (not $ret->{EMAILADDRESS}) {
446 0           my $h = $ret->{OPENSSL_EXTENSIONS}->{"X509v3 Subject Alternative Name"}[0];
447 0 0 0       if ($h && $h =~ /^(.*,|)\s*email:/i) {
448             ## email steckt im subjectAltName
449 0           $h =~ s/^(.*,|)\s*email:\s*//ig;
450 0           $h =~ s/\s*$//g;
451 0           $h =~ s/,.*$//g;
452 0           $ret->{EMAILADDRESS} = $h;
453             }
454             }
455              
456 0           return $ret;
457             }
458              
459             sub getPEM {
460 0     0 0   my $self = shift;
461              
462 0 0         if ( $self->{certFormat} eq 'PEM' ) {
463 0           $self->{cert} =~ s/^\n*//;
464 0           $self->{cert} =~ s/\n*$/\n/;
465 0           return $self->{cert};
466             }
467 0 0         if (not $self->{pemCert}) {
468 0           $self->{pemCert} = $self->{backend}->dataConvert( DATA=>$self->{cert},
469             DATATYPE=>"CERTIFICATE",
470             INFORM=>$self->{certFormat},
471             OUTFORM=>"PEM" );
472 0 0         return $self->setError (7441005, "OpenCA::X509->getPEM: Cannot convert request to PEM-format ".
473             "(".$OpenCA::OpenSSL::errno.")\n".$OpenCA::OpenSSL::errval)
474             if (not $self->{pemCert});
475             }
476              
477             ## return $self->setError (7441011, "OpenCA::X509->getPEM: The certificate is not available in PEM-format.")
478             ## if (not $self->{pemCert});
479 0           return $self->{pemCert};
480             }
481              
482             sub getPEMHeader {
483 0     0 0   my $self = shift;
484              
485 0 0         return $self->setError (7442011, "OpenCA::X509->getPEMHeader: There is no PEM-header available.")
486             if (not $self->{pemHeader});
487 0           return $self->{pemHeader};
488             }
489              
490             sub getDER {
491 0     0 0   my $self = shift;
492              
493 0 0         if ( $self->{certFormat} eq 'DER' ) {
494 0           return $self->{cert};
495             }
496 0 0         if (not $self->{derCert}) {
497 0           $self->{derCert} = $self->{backend}->dataConvert( DATA=>$self->{cert},
498             DATATYPE=>"CERTIFICATE",
499             INFORM=>$self->{certFormat},
500             OUTFORM=>"DER" );
501 0 0         return $self->setError (7443005, "OpenCA::X509->getDER: Cannot convert request to DER-format ".
502             "(".$OpenCA::OpenSSL::errno.")\n".$OpenCA::OpenSSL::errval)
503             if (not $self->{derCert});
504             }
505              
506             ## return $self->setError (7443011, "OpenCA::X509->getDER: The certificate is not available in DER-format.")
507             ## if( not $self->{derCert} );
508 0           return $self->{derCert};
509             }
510              
511             sub getTXT {
512 0     0 0   my $self = shift;
513              
514 0 0         if (not $self->{txtCert}) {
515 0           $self->{txtCert} = $self->{backend}->dataConvert( DATA=>$self->{cert},
516             DATATYPE=>"CERTIFICATE",
517             INFORM=>$self->{certFormat},
518             OUTFORM=>"TXT" );
519 0 0         return $self->setError (7444005, "OpenCA::X509->init: Cannot convert request to TXT-format ".
520             "(".$OpenCA::OpenSSL::errno.")\n".$OpenCA::OpenSSL::errval)
521             if (not $self->{txtCert});
522             }
523              
524             ## return $self->setError (7444011, "OpenCA::X509->getTXT: The certificate is not available in TXT-format.")
525             ## if( not $self->{txtCert} );
526 0           return $self->{txtCert};
527             }
528              
529             ## by michael bell to support signature in the header
530             ## 1) works actually only with PEM because automatical
531             ## transformation to DER etc. is a high risc
532             ## for a failure
533             ## 2) please submit only one attribute
534             sub setHeaderAttribute {
535              
536 0     0 0   my $self = shift;
537 0           my $keys = { @_ };
538              
539 0           my $beginHeader = $self->{beginHeader};
540 0           my $endHeader = $self->{endHeader};
541 0           my $beginAttribute = $self->{beginAttribute};
542 0           my $endAttribute = $self->{endAttribute};
543              
544             ## check certFormat to be PEM
545 0 0         return $self->setError (7451011, "OpenCA::X509->setHeaderAttribute: The request is not in PEM-format.")
546             if ($self->{certFormat} !~ /^PEM$/i);
547 0 0         print "X509->setHeaderAttribute: correct format - PEM
\n" if ($self->{DEBUG});
548              
549             ## check for header
550 0 0         if ($self->{item} !~ /$beginHeader/) {
551             ## create header
552 0           $self->{item} = $beginHeader."\n".$endHeader."\n".$self->{item};
553             }
554              
555 0           for my $attribute (keys %{$keys}) {
  0            
556              
557 0 0         print "X509->setHeaderAttribute: $attribute:=".$keys->{$attribute}."
\n" if ($self->{DEBUG});
558              
559             ## insert into item
560             ## find last position in header
561             ## enter attributename
562             ## check fo multirow
563 0 0         if ($keys->{$attribute} =~ /\n/) {
564             ## multirow
565 0           $self->{item} =~ s/${endHeader}/${attribute}=\n${beginAttribute}\n$keys->{$attribute}\n${endAttribute}\n${endHeader}/;
566             } else {
567             ## single row
568 0           $self->{item} =~ s/${endHeader}/${attribute}=$keys->{$attribute}\n${endHeader}/;
569             }
570              
571             }
572              
573             ## if you call init then all information is lost !!!
574 0 0         return $self->setError (7451021, "OpenCA::X509->setHeaderAttribute: Cannot re-initialize the certificate ".
575             "($errno)\n$errval")
576             if (not $self->init ( CERTIFICATE => $self->{item},
577             FORMAT => "PEM"));
578              
579 0           return 1;
580             }
581              
582             sub getItem {
583 0     0 0   my $self = shift;
584 0           my $txtItem = "";
585 0           my $bH = $self->{beginHeader};
586 0           my $eH = $self->{endHeader};
587              
588             ## remove empty header
589 0 0         if ($self->getPEMHeader() !~ /^\n*$bH\n*$eH\n*$/) {
590 0           $txtItem .= $self->getPEMHeader ()."\n";
591             }
592 0           $txtItem .= $self->getPEM();
593 0   0       $txtItem .= $self->getParsed()->{KEY} || "";
594              
595 0           return $txtItem;
596             }
597              
598             sub getSerial {
599 0     0 0   my $self = shift;
600              
601 0 0 0       if (defined $_[0] and ( ($_[0] =~ /^CA/i) or ($_[0] =~ /CA_/i)) ) {
      0        
602 0           return $self->{backend}->getDigest ( DATA => $self->getPEM() );
603             } else {
604 0           return $self->getParsed()->{SERIAL};
605             }
606             }
607              
608             sub setParams {
609              
610 0     0 0   my $self = shift;
611 0           my $params = { @_ };
612 0           my $key;
613              
614 0           foreach $key ( keys %{$params} ) {
  0            
615             ## we should place the parameters here
616             }
617              
618 0           return 1;
619             }
620              
621             # Autoload methods go after =cut, and are processed by the autosplit program.
622              
623             1;