line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package VOMS::Lite::PROXY; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
1682
|
use 5.004; |
|
1
|
|
|
|
|
5
|
|
|
1
|
|
|
|
|
47
|
|
4
|
1
|
|
|
1
|
|
7
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
44
|
|
5
|
1
|
|
|
1
|
|
6
|
use VOMS::Lite::PEMHelper qw(readCert readAC readPrivateKey); |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
75
|
|
6
|
1
|
|
|
1
|
|
6
|
use VOMS::Lite::CertKeyHelper qw(digestSign); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
71
|
|
7
|
1
|
|
|
1
|
|
6
|
use VOMS::Lite::ASN1Helper qw(ASN1Wrap ASN1Unwrap DecToHex Hex ASN1BitStr); |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
76
|
|
8
|
1
|
|
|
1
|
|
6
|
use VOMS::Lite::KEY; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
34
|
|
9
|
1
|
|
|
1
|
|
6
|
use VOMS::Lite::X509; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
29
|
|
10
|
1
|
|
|
1
|
|
5
|
use VOMS::Lite::RSAKey; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
46
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
require Exporter; |
13
|
1
|
|
|
1
|
|
6
|
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
2650
|
|
14
|
|
|
|
|
|
|
@ISA = qw(Exporter); |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
$VERSION = '0.20'; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
sub Examine { |
19
|
0
|
|
|
0
|
0
|
0
|
return VOMS::Lite::X509::Examine(@_); |
20
|
|
|
|
|
|
|
} |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
sub Create { |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
# Load in Context |
25
|
1
|
|
|
1
|
0
|
390
|
my %context = %{ shift() }; |
|
1
|
|
|
|
|
6
|
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
# Create error and warning arrays |
28
|
1
|
|
|
|
|
3
|
my @Errors; |
29
|
|
|
|
|
|
|
my @Warnings; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# Get request time; |
32
|
1
|
|
|
|
|
3
|
my $now=time(); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# Check for required input values |
35
|
1
|
50
|
|
|
|
6
|
if ( ! defined $context{'Cert'} ) { push @Errors, "PROXY: Issuer certificate not supplied"; } |
|
0
|
|
|
|
|
0
|
|
36
|
1
|
50
|
|
|
|
4
|
if ( ! defined $context{'Key'} ) { push @Errors, "PROXY: Issuer key not supplied"; } |
|
0
|
|
|
|
|
0
|
|
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
# Bail if there isn't enough information |
39
|
1
|
50
|
|
|
|
4
|
if ( @Errors > 0 ) { return { Errors => \@Errors} ; } |
|
0
|
|
|
|
|
0
|
|
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# Load input data into local variables |
42
|
1
|
50
|
|
|
|
15
|
my $CertInfoRef = (($context{'Cert'} =~ /^(\060.+)$/s) ? VOMS::Lite::X509::Examine($&, {X509serial=>"", X509subject=>"", End=>""}) : undef); |
43
|
1
|
50
|
|
|
|
20
|
my $KeyInfoRef = (($context{'Key'} =~ /^(\060.+)$/s) ? VOMS::Lite::KEY::Examine($&, {Keymodulus=>"", KeyprivateExponent=>""}) : undef); |
44
|
1
|
50
|
|
|
|
3
|
my %CI; if ( defined $CertInfoRef ) { %CI=%$CertInfoRef; } else { push @Errors, "PROXY: Unable to parse certificate."; } |
|
1
|
|
|
|
|
15
|
|
|
1
|
|
|
|
|
6
|
|
|
0
|
|
|
|
|
0
|
|
45
|
1
|
50
|
|
|
|
13
|
my %KI; if ( defined $KeyInfoRef ) { %KI=%$KeyInfoRef; } else { push @Errors, "PROXY: Unable to parse key."; } |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
4
|
|
|
0
|
|
|
|
|
0
|
|
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
# Bail if there is a certificate Parse error |
48
|
1
|
50
|
|
|
|
4
|
if ( @Errors > 0 ) { return { Errors => \@Errors} ; } |
|
0
|
|
|
|
|
0
|
|
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# Load optional values |
51
|
1
|
50
|
33
|
|
|
12
|
my $type = ((( defined $context{'Type'} && $context{'Type'} =~ /^(Lega[cs]y|Limited|Pre-RFC|RFC)$/) ) ? $& : undef); |
52
|
1
|
50
|
|
|
|
4
|
if ( $type eq "Legasy" ) { $type = "Legacy"; $context{'Type'}="Legacy"; } # oops was going through a bad spell! |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
53
|
1
|
50
|
33
|
|
|
6
|
my $pathlen = ((( defined $context{'PathLength'} && $context{'PathLength'} =~ /^([0-9]+)$/s) ) ? $& : undef); |
54
|
1
|
50
|
33
|
|
|
4
|
my $bits = ((( defined $context{'Bits'} && $context{'Bits'} =~ /^(512|1024|2048|4096)$/s) ) ? $& : undef); |
55
|
1
|
50
|
33
|
|
|
11
|
my $lifetime = ((( defined $context{'Lifetime'} && $context{'Lifetime'} =~ /^([0-9]+)$/s) ) ? $& : undef); |
56
|
1
|
50
|
33
|
|
|
6
|
my $start = ((( defined $context{'Start'} && $context{'Start'} =~ /^([0-9]+)$/s) ) ? $& : undef); |
57
|
1
|
50
|
33
|
|
|
5
|
my $AC = ((( defined $context{'AC'} && $context{'AC'} =~ /^(\060.+)$/s) ) ? $& : undef); |
58
|
1
|
|
|
|
|
2
|
my @Ext; |
59
|
1
|
50
|
|
|
|
4
|
if ( defined $context{'Ext'} ) { |
60
|
0
|
0
|
|
|
|
0
|
if ( ref ($context{'Ext'}) eq "ARRAY" ) { @Ext = @{ $context{'Ext'} }; } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
61
|
0
|
|
|
|
|
0
|
else { push @Errors,"PROXY: Ext must be an array reference"; } |
62
|
|
|
|
|
|
|
}; |
63
|
1
|
0
|
|
|
|
3
|
foreach (@Ext) { if ( ! /^(\060.+)$/ ) { push @Errors,"Extension ".Hex($1)." isn't DER encoded"; } } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
64
|
1
|
50
|
33
|
|
|
5
|
my $KeypublicE = ((( defined $context{'KeypublicExponent'} && $context{'KeypublicExponent'} =~ /^([\x00-\x7f].+)$/s) ) ? $& : undef); |
65
|
1
|
50
|
33
|
|
|
5
|
my $KeypublicM = ((( defined $context{'KeypublicModulus'} && $context{'KeypublicModulus'} =~ /^([\x00-\x7f].+)$/s) ) ? $& : undef); |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
# Check for unrecognised values for recognised options |
68
|
1
|
50
|
33
|
|
|
6
|
if ( defined $context{'Type'} && ! defined $type ) { push @Errors, "PROXY: Unknown proxy type $context{'Type'}. Try Legacy, Limited, Pre-RFC or RFC."; } |
|
0
|
|
|
|
|
0
|
|
69
|
1
|
50
|
33
|
|
|
33
|
if ( defined $context{'PathLength'} && ! defined $pathlen ) { push @Errors, "PROXY: Invalid Pathlength $context{'PathLength'}. Must be a positive integer."; } |
|
0
|
|
|
|
|
0
|
|
70
|
1
|
50
|
33
|
|
|
3
|
if ( defined $context{'Bits'} && ! defined $bits ) { push @Errors, "PROXY: Key size may only be 512, 1024, 2048 or 4096."; } |
|
0
|
|
|
|
|
0
|
|
71
|
1
|
50
|
33
|
|
|
7
|
if ( defined $context{'Lifetime'} && ! defined $lifetime ) { push @Errors, "PROXY: Invalid Lifetime $context{'Lifetime'}. Must be a positive integer."; } |
|
0
|
|
|
|
|
0
|
|
72
|
1
|
50
|
33
|
|
|
4
|
if ( defined $context{'Start'} && ! defined $start ) { push @Errors, "PROXY: Invalid Start $context{'Start'}. Must be a positive integer (seconds since epoch)."; } |
|
0
|
|
|
|
|
0
|
|
73
|
1
|
50
|
33
|
|
|
5
|
if ( defined $context{'AC'} && ! defined $AC ) { push @Errors, "PROXY: AC Must be in DER format."; } |
|
0
|
|
|
|
|
0
|
|
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# Check for unknown options |
76
|
1
|
50
|
|
|
|
2
|
foreach (keys %context) { if ( ! /^(Quiet|Type|PathLength|Lifetime|AC|Ext|Cert|Key|Start|Bits|KeypublicExponent|KeypublicModulus)$/ ) { push @Errors, "PROXY: $_ is an invalid option.";}} |
|
4
|
|
|
|
|
15
|
|
|
0
|
|
|
|
|
0
|
|
77
|
|
|
|
|
|
|
|
78
|
1
|
50
|
|
|
|
4
|
if ( defined $start ) { $now = $start;} |
|
0
|
|
|
|
|
0
|
|
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# Bail if any recognised options are invalid |
81
|
1
|
50
|
|
|
|
4
|
if ( @Errors > 0 ) { return { Errors => \@Errors} ; } |
|
0
|
|
|
|
|
0
|
|
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
# Warn if there is something queer |
84
|
1
|
50
|
|
|
|
4
|
if ( ! defined $type ) { $type = "Legacy"; push @Warnings, "PROXY: Undefined proxy type. Defaulting to Legacy."; } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
85
|
1
|
50
|
|
|
|
3
|
if ( ! defined $lifetime ) { $lifetime = 43200; push @Warnings, "PROXY: Undefined lifetime. Defaulting to $lifetime seconds."; } |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
86
|
1
|
50
|
|
|
|
3
|
if ( ! defined $bits ) { $bits = 512; push @Warnings, "PROXY: Undefined key size. Defaulting to $bits bits."; } |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
3
|
|
87
|
1
|
50
|
|
|
|
4
|
if ( $lifetime > 86400 ) { push @Warnings, "PROXY: Requested lifetime exceeds 24 hours."; } |
|
0
|
|
|
|
|
0
|
|
88
|
1
|
50
|
|
|
|
3
|
if ( ( $lifetime ) > ( $CI{'End'} - $now ) ) { push @Warnings, "PROXY: Requested lifetime exceeds lifetime of issuer."; } |
|
0
|
|
|
|
|
0
|
|
89
|
1
|
50
|
|
|
|
4
|
if ( ( $CI{'End'} - $now ) < 604800 ) { push @Warnings, "PROXY: Issuer certificate will expire in less than 1 week."; } |
|
1
|
|
|
|
|
2
|
|
90
|
1
|
50
|
33
|
|
|
8
|
if ( $type =~ "Legacy" && defined $pathlen ) { push @Warnings, "PROXY: Legacy Proxy may not a proxy pathlength."; } |
|
0
|
|
|
|
|
0
|
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
################################################################### |
93
|
|
|
|
|
|
|
# Do not edit below these lines (unless there's a bug of course!) # |
94
|
|
|
|
|
|
|
################################################################### |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
#Get times Now and Now + $lifetime (12 hours) |
97
|
1
|
|
|
|
|
6
|
my @NOW=gmtime($now ); |
98
|
1
|
|
|
|
|
4
|
my @FUT=gmtime($now + $lifetime ); |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
# UTCTIME (so two digit years, OK for the next 40 or so years!) |
101
|
1
|
|
|
|
|
10
|
my $beforeDate=sprintf("%02i%02i%02i%02i%02i%02iZ",($NOW[5] % 100),($NOW[4]+1),$NOW[3],$NOW[2],$NOW[1],$NOW[0]); |
102
|
1
|
|
|
|
|
5
|
my $afterDate=sprintf("%02i%02i%02i%02i%02i%02iZ",($FUT[5] % 100),($FUT[4]+1),$FUT[3],$FUT[2],$FUT[1],$FUT[0]); |
103
|
|
|
|
|
|
|
|
104
|
1
|
|
|
|
|
1
|
my ( $Keyversion, $Keymodulus, $KeypublicExponent, $KeyprivateExponent, $Keyprime1, $Keyprime2, $Keyexponent1, $Keyexponent2, $Keycoefficient, $Privatekey); |
105
|
|
|
|
|
|
|
|
106
|
1
|
50
|
33
|
|
|
5
|
if ( ! defined($KeypublicE) || ! defined($KeypublicM) ) { |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# Generate Key Pair |
109
|
1
|
50
|
|
|
|
10
|
my $keyref = VOMS::Lite::RSAKey::Create( { Bits => $bits, Verbose => (defined $context{'Quiet'})?undef:"y" } ); |
110
|
1
|
50
|
|
|
|
8
|
if ( ! defined $keyref ) { return { Errors => [ "PROXY: Key Generation Failure" ] } ; } |
|
0
|
|
|
|
|
0
|
|
111
|
1
|
|
|
|
|
3
|
my %key = %{ $keyref }; |
|
1
|
|
|
|
|
10
|
|
112
|
1
|
50
|
|
|
|
7
|
if ( defined $key{'Errors'} ) { return { Errors => [ "PROXY: Error in Key Generation ".$key{'Errors'} ] } ; } |
|
0
|
|
|
|
|
0
|
|
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
### Proxy Private Key##################################################### |
115
|
|
|
|
|
|
|
# Keyversion Keymodulus KeypublicExponent KeyprivateExponent |
116
|
|
|
|
|
|
|
# Keyprime1 Keyprime2 Keyexponent1 Keyexponent2 Keycoefficient |
117
|
1
|
|
|
|
|
3
|
$Keyversion = "020100"; |
118
|
1
|
|
|
|
|
9
|
$Keymodulus = ASN1Wrap("02",DecToHex($key{Modulus})); |
119
|
1
|
|
|
|
|
7
|
$KeypublicExponent = ASN1Wrap("02",DecToHex($key{PublicExponent})); |
120
|
1
|
|
|
|
|
6
|
$KeyprivateExponent = ASN1Wrap("02",DecToHex($key{PrivateExponent})); |
121
|
1
|
|
|
|
|
8
|
$Keyprime1 = ASN1Wrap("02",DecToHex($key{Prime1})); |
122
|
1
|
|
|
|
|
9
|
$Keyprime2 = ASN1Wrap("02",DecToHex($key{Prime2})); |
123
|
1
|
|
|
|
|
5
|
$Keyexponent1 = ASN1Wrap("02",DecToHex($key{Exponent1})); |
124
|
1
|
|
|
|
|
7
|
$Keyexponent2 = ASN1Wrap("02",DecToHex($key{Exponent2})); |
125
|
1
|
|
|
|
|
8
|
$Keycoefficient = ASN1Wrap("02",DecToHex($key{Iqmp})); |
126
|
|
|
|
|
|
|
|
127
|
1
|
|
|
|
|
10
|
$Privatekey=ASN1Wrap("30",$Keyversion.$Keymodulus.$KeypublicExponent.$KeyprivateExponent. |
128
|
|
|
|
|
|
|
$Keyprime1.$Keyprime2.$Keyexponent1.$Keyexponent2.$Keycoefficient); |
129
|
|
|
|
|
|
|
} else { |
130
|
0
|
|
|
|
|
0
|
$Keymodulus = ASN1Wrap("02",Hex($KeypublicM)); |
131
|
0
|
|
|
|
|
0
|
$KeypublicExponent = ASN1Wrap("02",Hex($KeypublicE)); |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
###Proxy Public Bits###################################################### |
135
|
|
|
|
|
|
|
# TBSCertificate: |
136
|
|
|
|
|
|
|
# X509version X509serial X509signature X509issuer X509validity X509subject |
137
|
|
|
|
|
|
|
# X509subjectPublicKeyInfo (X509issuerUniqueID) (X509subjectUniqueID) X509extensions |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
#Certificate Version (x509 v3) |
140
|
1
|
|
|
|
|
4
|
my $X509version = "a003020102"; |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
#Serial Number (different algorithm for (Pre)?RFC and Legacy Globus |
143
|
1
|
|
|
|
|
9
|
my $SN=DecToHex( ((($CI{End}-$now) & hex("00ffffff"))<<8 ) + int(rand 256)); |
144
|
1
|
50
|
|
|
|
9
|
my $X509serial=($type eq "Legacy")?Hex($CI{X509serial}):ASN1Wrap("02",$SN); |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
#Use MD5 and RSA for now |
147
|
1
|
|
|
|
|
3
|
my $X509signature="300d06092a864886f70d0101040500"; #SEQ(OID:md5WithRSAEncryption NULL) |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
#Issuer (straight from certificate) |
150
|
1
|
|
|
|
|
5
|
my $X509issuer=Hex($CI{X509subject}); |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
#Validity |
153
|
1
|
|
|
|
|
6
|
my $X509Validity=ASN1Wrap("30",ASN1Wrap("17",Hex($beforeDate)).ASN1Wrap("17",Hex($afterDate))); |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
#Subject |
156
|
1
|
|
|
|
|
7
|
my $proxystr = Hex("proxy"); |
157
|
1
|
50
|
|
|
|
5
|
$proxystr = Hex("limited proxy") if ($type eq "Limited"); |
158
|
1
|
50
|
33
|
|
|
29
|
$proxystr = Hex(hex($SN)) if ($type ne "Legacy" && $type ne "Limited"); |
159
|
1
|
|
|
|
|
5
|
my $PROXYNAME=ASN1Wrap("31",ASN1Wrap("30","0603550403".ASN1Wrap("13",$proxystr))); #SET{SEQ{OID:CN CN}} |
160
|
1
|
|
|
|
|
8
|
my $X509subject=ASN1Wrap("30",Hex(scalar ASN1Unwrap($CI{X509subject})).$PROXYNAME); |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
#Public Key |
163
|
1
|
|
|
|
|
7
|
my $PubKeyChunck=ASN1Wrap("30",$Keymodulus.$KeypublicExponent); |
164
|
1
|
|
|
|
|
5
|
my $X509subjectPublicKeyInfo=ASN1Wrap("30",ASN1Wrap("30","06092a864886f70d0101010500").ASN1Wrap("03",ASN1BitStr($PubKeyChunck))); |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
#Extensions |
167
|
|
|
|
|
|
|
#KeyUsage |
168
|
1
|
|
|
|
|
5
|
my $keyusage=ASN1Wrap("30","0603551d0f"."0101ff"."0404030203a8");#Critical:Dig sign & Key encypher & Key Agree |
169
|
|
|
|
|
|
|
######Proxyinfo not quite right yet |
170
|
|
|
|
|
|
|
#ProxyInfo Extensions SEQ{OID(GlobusProxy|id-ppl-inheritALL) . Criticality . PolicyLangOID+Policy} |
171
|
1
|
50
|
|
|
|
5
|
my $PolicyVal=( defined $pathlen )?ASN1Wrap("a1",ASN1Wrap("02",DecToHex($pathlen))):""; |
172
|
1
|
|
|
|
|
3
|
my $Policy; |
173
|
1
|
50
|
|
|
|
5
|
$Policy=ASN1Wrap("04",ASN1Wrap("30","300a06082b06010505071501".$PolicyVal)) if ($type eq "Pre-RFC"); |
174
|
1
|
50
|
|
|
|
4
|
$Policy=ASN1Wrap("04",ASN1Wrap("30",$PolicyVal."300a06082b06010505071501")) if ($type eq "RFC"); |
175
|
1
|
|
|
|
|
1
|
my $ProxyInfo=""; |
176
|
1
|
50
|
|
|
|
3
|
$ProxyInfo=ASN1Wrap("30","060a2b060104019b5001815e"."0101ff".$Policy) if ($type eq "Pre-RFC"); |
177
|
1
|
50
|
|
|
|
4
|
$ProxyInfo=ASN1Wrap("30","06082b0601050507010e". "0101ff".$Policy) if ($type eq "RFC"); |
178
|
|
|
|
|
|
|
#VOMS |
179
|
1
|
|
|
|
|
2
|
my $VOMS=""; |
180
|
|
|
|
|
|
|
# $VOMS=ASN1Wrap("30","060a2b06010401be45646405"."".ASN1Wrap("04",Hex($AC))) if ( defined $AC ); |
181
|
1
|
50
|
|
|
|
5
|
$VOMS=ASN1Wrap("30","060a2b06010401be45646405"."".ASN1Wrap("04",ASN1Wrap("30",ASN1Wrap("30",Hex($AC))))) if ( defined $AC ); |
182
|
|
|
|
|
|
|
|
183
|
1
|
|
|
|
|
7
|
my $X509extensions=ASN1Wrap("a3",ASN1Wrap("30",$keyusage.$ProxyInfo.$VOMS.Hex(join('',@Ext)))); |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
#The whole chunck of certificate to be signed |
186
|
1
|
|
|
|
|
9
|
my $TBSCertificate=ASN1Wrap("30",$X509version.$X509serial.$X509signature.$X509issuer.$X509Validity. |
187
|
|
|
|
|
|
|
$X509subject.$X509subjectPublicKeyInfo.$X509extensions); |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
###Signature Bits##################################################### |
190
|
|
|
|
|
|
|
# X509signatureAlgorithm X509signature |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
# Make MD5 Checksum and RSA sign it |
193
|
1
|
|
|
|
|
3
|
my $BinaryTBSCertificate = $TBSCertificate; |
194
|
1
|
|
|
|
|
6
|
$BinaryTBSCertificate =~ s/(..)/pack('C',hex($&))/ge; |
|
309
|
|
|
|
|
743
|
|
195
|
1
|
|
|
|
|
7
|
my $RSAsignedDigest = digestSign("md5WithRSA",$BinaryTBSCertificate,Hex($KI{KeyprivateExponent}),Hex($KI{Keymodulus})); |
196
|
1
|
|
|
|
|
10
|
my $Signature = ASN1Wrap("03",ASN1BitStr($RSAsignedDigest)); #(Always n*8 bits for MDnRSA and SHA1RSA) |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
###Wrap it all up Public Bits and Signature############################ |
200
|
|
|
|
|
|
|
# TBSCertificate X509signatureAlgorithm X509signature |
201
|
|
|
|
|
|
|
|
202
|
1
|
|
|
|
|
10
|
my $Certificate = ASN1Wrap("30",$TBSCertificate.$X509signature.$Signature); |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
###Write out the proxy to the proxy file############################### |
205
|
|
|
|
|
|
|
# ProxyCert ProxyKey SigningCerts ##### Would like to put full chain in here! |
206
|
|
|
|
|
|
|
|
207
|
1
|
|
|
|
|
10
|
$Certificate=~s/(..)/pack('C',hex($&))/ge; |
|
395
|
|
|
|
|
950
|
|
208
|
1
|
50
|
33
|
|
|
11
|
if ( ! defined($KeypublicE) || ! defined($KeypublicM) ) { $Privatekey=~s/(..)/pack('C',hex($&))/ge; } |
|
1
|
|
|
|
|
6
|
|
|
318
|
|
|
|
|
1066
|
|
209
|
|
|
|
|
|
|
|
210
|
1
|
|
|
|
|
40
|
return { ProxyCert=>$Certificate, ProxyKey=>$Privatekey, Warnings=>\@Warnings }; |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
1; |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
__END__ |