VOMS-Lite
view release on metacpan or search on metacpan
lib/VOMS/Lite/VOMS.pm view on Meta::CPAN
push @ReqASN1DN,substr($ReqDistinguishedNames,0,$DNLen,'');
}
# Get ServerHelloDone
my $sHelloDone=$Hand{14};
# Check for RSA
if ($RSAOK==0) { return { Errors => ErrWarn("Server does not support RSA AuthN"), Warnings => \@warning }; }
# 1, Check acceptable DNs for Certificates
my $GotCA=0;
foreach (@ReqASN1DN) {
my $X509subject=$_;
my @ASN1SubjectDNIndex=ASN1Index($X509subject);
shift @ASN1SubjectDNIndex;
my $SubjectDN="";
while (@ASN1SubjectDNIndex) {
my ($CLASS,$CONSTRUCTED,$TAG,$HEADSTART,$HEADLEN,$CHUNKLEN)=(0,0,0,0,0);
until ($TAG == 6 ) { ($CLASS,$CONSTRUCTED,$TAG,$HEADSTART,$HEADLEN,$CHUNKLEN) = @{shift @ASN1SubjectDNIndex}; }
my $OID=substr($X509subject,($HEADSTART+$HEADLEN),$CHUNKLEN);
($CLASS,$CONSTRUCTED,$TAG,$HEADSTART,$HEADLEN,$CHUNKLEN) = @{shift @ASN1SubjectDNIndex};
my $Value=substr($X509subject,($HEADSTART+$HEADLEN),$CHUNKLEN);
$SubjectDN.="/".VOMS::Lite::CertKeyHelper::OIDtoDNattrib(ASN1OIDtoOID($OID))."=$Value";
}
if ($UserIDN eq $SubjectDN) { debug("MATCHED CA",$SubjectDN); $GotCA=1; }
else { debug(" CA:", $SubjectDN); }
}
if ( @ReqASN1DN == 0 ) { ErrWarn(\@warning, "VOMS server does not tell me what CAs are supported"); }
elsif ( $GotCA==0 ) { return { Errors => ErrWarn("VOMS server does not support your CA"), Warnings => \@warning }; }
#########################################################
#Talk to the server again
##Construct Certificate Message Record
my $hexcertarray ="";
foreach my $cert (@chain) { $hexcertarray.=sprintf("%06s",DecToHex(length($cert))).Hex($cert);}
my $hexcertobj = sprintf("%06s",DecToHex(length($hexcertarray)/2)).$hexcertarray;
my $hexcertmesg = handShake("0b",$hexcertobj);
my $hexcertsmessagerecord=recordLayer("16",$hexcertmesg);
my $certmesg = pack("H*", $hexcertmesg);
##ClientKeyExchange
#PreMasterSecret
my $prernd='X' x 46; $prernd =~ s/./chr(int(rand 256))/ge;
my $hexpremastersecret='0300'.Hex($prernd);
#Derive Key Material
my %KEYS=Keygen($hexpremastersecret,$hexrandom,Hex($sHelloTime.$sHelloRand));
#Make Client Key Exchange
my $hexEncPMSecret = rsaencrypt($hexpremastersecret,Hex($ServerCertInfo{'KeypublicExponent'}),Hex($ServerCertInfo{'Keymodulus'}));
my $hexClientKeyExchange = handShake("10",$hexEncPMSecret); #### USE ME FOR CertificateVarify
my $hexClientKeyExchangeMessageRecord = recordLayer("16",$hexClientKeyExchange);
my $ClientKeyExchangeMessage = Bin($hexClientKeyExchange); #### ClientCertificate for handshakemessages needs to be without record layer
#CertificateVerify
my $Hmsgs = $clienthello.$serverhello.$certmesg.$ClientKeyExchangeMessage;
my $verifymac = MAC($KEYS{'MS'},$Hmsgs);
my $hexsignedcertificateverify = rsasign($verifymac,$Keyexp,$Keymod);
my $hexwrappedsignedcertificateverify = sprintf("%04s",DecToHex(length($hexsignedcertificateverify)/2)).$hexsignedcertificateverify;
my $hexcertificateverify = handShake('0f',$hexwrappedsignedcertificateverify);
my $certificateverify = Bin($hexcertificateverify);
my $hex_ssl_certificateverifyrecord = recordLayer("16",$hexcertificateverify);
##########################################################################
## Switch to Encrypted Session -- change_cipher_spec message
#Select algorythm for key exchange -- Must be RSA
my $hexkeyselection="140300000101";
# Switch to tripple des (the only one I support) and send finished message
$Hmsgs.=$certificateverify;
my $unechexfinished=handShake("14",MAC($KEYS{'MS'},$Hmsgs."CLNT"));
#Set up the Client and Server DES3-EDE sessions
my $Ccipher = Crypt::CBC->new( -literal_key => 1, -padding => 'null', -key => $KEYS{'CK'}, -iv => $KEYS{'CIV'}, -header => 'none', -cipher => 'DES_EDE3' );
my $Scipher = Crypt::CBC->new( -literal_key => 1, -padding => 'null', -key => $KEYS{'SK'}, -iv => $KEYS{'SIV'}, -header => 'none', -cipher => 'DES_EDE3' );
my $Cseq=0;
my $Sseq=0;
my $hex_finishedrecord = &Encrypt(Bin(recordLayer("16",$unechexfinished)),$KEYS{'CMAC'},$pad1sha,$pad2sha,$Cseq,$Ccipher);
my $hex_finished = $hex_finishedrecord;
$hex_finished =~ s/^..........//s;
my $finished = Bin($hex_finished);
#############################################################################
#Send Records
Write($sock,Bin($hexcertsmessagerecord.$hexClientKeyExchangeMessageRecord.$hex_ssl_certificateverifyrecord.$hexkeyselection.$hex_finishedrecord));
#############################################################################
#Receive Response
$response=Read($sock);
if ( $response =~ /^\x14\x03\x00\x00\x01\x01/ ) { $response =~ s/......//; } #Change Cypher Spec -- what we expect
else { return { Errors => ErrWarn("Error: Expecting SSL Change Cypher Spec Message, got something else."), Warnings => \@warning }; }
my $serverfinishedhex=Hex(&Decrypt($response,$KEYS{'SMAC'},$pad1sha,$pad2sha,$Sseq,$Scipher));
# Check response from server is a valid finished message
$Hmsgs.=Bin($unechexfinished);
my $unencryptedfinishedmsg = handShake("14",MAC($KEYS{'MS'},$Hmsgs."SRVR"));
if ($unencryptedfinishedmsg ne $serverfinishedhex) { return { Errors => ErrWarn("Failed to decrypt Server Finished Message"), Warnings => \@warning }; }
#########################
# Send no delegation byte
# predata and postdata to stop TLS CBC IV attack
my $predata = Bin(&Encrypt(Bin("1703000000"),$KEYS{'CMAC'},$pad1sha,$pad2sha,$Cseq,$Ccipher));
my $msg='0';
my $emesg = &Encrypt(Bin(recordLayer("17",Hex($msg))),$KEYS{'CMAC'},$pad1sha,$pad2sha,$Cseq,$Ccipher);
$senddata = Bin($emesg);
my $postdata = Bin(&Encrypt(Bin("1703000000"),$KEYS{'CMAC'},$pad1sha,$pad2sha,$Cseq,$Ccipher));
Write($sock,$predata.$senddata.$postdata);
##############
# Send request
#<xml version="1.0" encoding = "US-ASCII"?>
# <voms>
# <command>COMMAND</command>+
# <order>ORDER</order>?
# <targets>TARGETS</targets>?
# <lifetime>N</lifetime>?
# <base64>B</base64>?
lib/VOMS/Lite/VOMS.pm view on Meta::CPAN
push @ReqASN1DN,substr($ReqDistinguishedNames,0,$DNLen,'');
}
# Get ServerHelloDone
my $sHelloDone=$Hand{14};
# Check for RSA
if ($RSAOK==0) { return { Errors => ErrWarn("Server does not support RSA AuthN"), Warnings => \@warning }; }
# 1, Check acceptable DNs for Certificates
my $GotCA=0;
foreach (@ReqASN1DN) {
my $X509subject=$_;
my @ASN1SubjectDNIndex=ASN1Index($X509subject);
shift @ASN1SubjectDNIndex;
my $SubjectDN="";
while (@ASN1SubjectDNIndex) {
my ($CLASS,$CONSTRUCTED,$TAG,$HEADSTART,$HEADLEN,$CHUNKLEN)=(0,0,0,0,0);
until ($TAG == 6 ) { ($CLASS,$CONSTRUCTED,$TAG,$HEADSTART,$HEADLEN,$CHUNKLEN) = @{shift @ASN1SubjectDNIndex}; }
my $OID=substr($X509subject,($HEADSTART+$HEADLEN),$CHUNKLEN);
($CLASS,$CONSTRUCTED,$TAG,$HEADSTART,$HEADLEN,$CHUNKLEN) = @{shift @ASN1SubjectDNIndex};
my $Value=substr($X509subject,($HEADSTART+$HEADLEN),$CHUNKLEN);
$SubjectDN.="/".VOMS::Lite::CertKeyHelper::OIDtoDNattrib(ASN1OIDtoOID($OID))."=$Value";
}
if ($UserIDN eq $SubjectDN) { debug("MATCHED CA",$SubjectDN); $GotCA=1; }
else { debug(" CA:", $SubjectDN); }
}
if ( @ReqASN1DN == 0 ) { ErrWarn(\@warning, "VOMS server does not tell me what CAs are supported"); }
elsif ( $GotCA==0 ) { return { Errors => ErrWarn("VOMS server does not support your CA"), Warnings => \@warning }; }
#########################################################
#Talk to the server again
##Construct Certificate Message Record
my $hexcertarray ="";
foreach my $cert (@chain) { $hexcertarray.=sprintf("%06s",DecToHex(length($cert))).Hex($cert);}
my $hexcertobj = sprintf("%06s",DecToHex(length($hexcertarray)/2)).$hexcertarray;
my $hexcertmesg = handShake("0b",$hexcertobj);
my $hexcertsmessagerecord=recordLayer("16",$hexcertmesg);
my $certmesg = pack("H*", $hexcertmesg);
##ClientKeyExchange
#PreMasterSecret
my $prernd='X' x 46; $prernd =~ s/./chr(int(rand 256))/ge;
my $hexpremastersecret='0300'.Hex($prernd);
#Derive Key Material
my %KEYS=Keygen($hexpremastersecret,$hexrandom,Hex($sHelloTime.$sHelloRand));
#Make Client Key Exchange
my $hexEncPMSecret = rsaencrypt($hexpremastersecret,Hex($ServerCertInfo{'KeypublicExponent'}),Hex($ServerCertInfo{'Keymodulus'}));
my $hexClientKeyExchange = handShake("10",$hexEncPMSecret); #### USE ME FOR CertificateVarify
my $hexClientKeyExchangeMessageRecord = recordLayer("16",$hexClientKeyExchange);
my $ClientKeyExchangeMessage = Bin($hexClientKeyExchange); #### ClientCertificate for handshakemessages needs to be without record layer
#CertificateVerify
my $Hmsgs = $clienthello.$serverhello.$certmesg.$ClientKeyExchangeMessage;
my $verifymac = MAC($KEYS{'MS'},$Hmsgs);
my $hexsignedcertificateverify = rsasign($verifymac,$Keyexp,$Keymod);
my $hexwrappedsignedcertificateverify = sprintf("%04s",DecToHex(length($hexsignedcertificateverify)/2)).$hexsignedcertificateverify;
my $hexcertificateverify = handShake('0f',$hexwrappedsignedcertificateverify);
my $certificateverify = Bin($hexcertificateverify);
my $hex_ssl_certificateverifyrecord = recordLayer("16",$hexcertificateverify);
##########################################################################
## Switch to Encrypted Session -- change_cipher_spec message
#Select algorythm for key exchange -- Must be RSA
my $hexkeyselection="140300000101";
# Switch to tripple des (the only one I support) and send finished message
$Hmsgs.=$certificateverify;
my $unechexfinished=handShake("14",MAC($KEYS{'MS'},$Hmsgs."CLNT"));
#Set up the Client and Server DES3-EDE sessions
my $Ccipher = Crypt::CBC->new( -literal_key => 1, -padding => 'null', -key => $KEYS{'CK'}, -iv => $KEYS{'CIV'}, -header => 'none', -cipher => 'DES_EDE3' );
my $Scipher = Crypt::CBC->new( -literal_key => 1, -padding => 'null', -key => $KEYS{'SK'}, -iv => $KEYS{'SIV'}, -header => 'none', -cipher => 'DES_EDE3' );
my $Cseq=0;
my $Sseq=0;
my $hex_finishedrecord = &Encrypt(Bin(recordLayer("16",$unechexfinished)),$KEYS{'CMAC'},$pad1sha,$pad2sha,$Cseq,$Ccipher);
my $hex_finished = $hex_finishedrecord;
$hex_finished =~ s/^..........//s;
my $finished = Bin($hex_finished);
#############################################################################
#Send Records
Write($sock,Bin($hexcertsmessagerecord.$hexClientKeyExchangeMessageRecord.$hex_ssl_certificateverifyrecord.$hexkeyselection.$hex_finishedrecord));
#############################################################################
#Receive Response
$response=Read($sock);
if ( $response =~ /^\x14\x03\x00\x00\x01\x01/ ) { $response =~ s/......//; } #Change Cypher Spec -- what we expect
else { return { Errors => ErrWarn("Error: Expecting SSL Change Cypher Spec Message, got something else."), Warnings => \@warning }; }
my $serverfinishedhex=Hex(&Decrypt($response,$KEYS{'SMAC'},$pad1sha,$pad2sha,$Sseq,$Scipher));
# Check response from server is a valid finished message
$Hmsgs.=Bin($unechexfinished);
my $unencryptedfinishedmsg = handShake("14",MAC($KEYS{'MS'},$Hmsgs."SRVR"));
if ($unencryptedfinishedmsg ne $serverfinishedhex) { return { Errors => ErrWarn("Failed to decrypt Server Finished Message"), Warnings => \@warning }; }
#########################
# Send no delegation byte
# predata and postdata to stop TLS CBC IV attack
my $predata = Bin(&Encrypt(Bin("1703000000"),$KEYS{'CMAC'},$pad1sha,$pad2sha,$Cseq,$Ccipher));
my $msg='0';
my $emesg = &Encrypt(Bin(recordLayer("17",Hex($msg))),$KEYS{'CMAC'},$pad1sha,$pad2sha,$Cseq,$Ccipher);
$senddata = Bin($emesg);
my $postdata = Bin(&Encrypt(Bin("1703000000"),$KEYS{'CMAC'},$pad1sha,$pad2sha,$Cseq,$Ccipher));
Write($sock,$predata.$senddata.$postdata);
##############
# Send request
#<xml version="1.0" encoding = "US-ASCII"?>
# <voms>
# <command>COMMAND</command>+
# <order>ORDER</order>?
# <targets>TARGETS</targets>?
# <lifetime>N</lifetime>?
# <base64>B</base64>?
( run in 0.813 second using v1.01-cache-2.11-cpan-71847e10f99 )