smime
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· 代码 · 共 574 行 · 第 1/2 页
TXT
574 行
$signopts = "";$encryptopts = "";$decodeopts = "";# pass -d option alongif (defined($opt_d)) { $signopts .= "-d \"$opt_d\" "; $encryptopts .= "-d \"$opt_d\" "; $decodeopts .= "-d \"$opt_d\" ";}if (defined($opt_S)) { $signopts .= "-N \"$opt_S\" ";}if (defined($opt_p)) { $signopts .= "-p \"$opt_p\" "; $decodeopts .= "-p \"$opt_p\" ";}if (defined($opt_E)) { @recipients = split(",", $opt_E); $encryptopts .= "-r "; $encryptopts .= join (" -r ", @recipients);}if (defined($opt_C)) { $cmsutilpath = $opt_C;}## split headers into mime entity headers and RFC822 headers# The RFC822 headers are preserved and stay on the outer layer of the message#$rfc822headers = "";$mimeheaders = "";$mimebody = "";$skippedheaders = "";while (<STDIN>) { last if (/^$/); if (/^content-\S+: /i) { $lastref = \$mimeheaders; } elsif (/^mime-version: /i) { $lastref = \$skippedheaders; # skip it } elsif (/^\s/) { ; } else { $lastref = \$rfc822headers; } $$lastref .= $_;}## if there are no MIME entity headers, generate some default ones#if ($mimeheaders eq "") { $mimeheaders .= "Content-Type: text/plain; charset=us-ascii\n"; $mimeheaders .= "Content-Transfer-Encoding: 7bit\n";}## slurp in the entity body#$saveRS = $/;$/ = undef;$mimebody = <STDIN>;$/ = $saveRS;if (defined $opt_D) { # # decode # # possible options would be: # - strip off only one layer # - strip off outer signature (if present) # - just print information about the structure of the message # - strip n layers, then dump DER of CMS message $layercounter = 1; while (1) { %hdrhash = parseheaders($mimeheaders); unless (exists($hdrhash{"content-type"}{MAIN})) { print STDERR "ERROR: no content type header found in MIME entity\n"; last; # no content-type - we're done } $contenttype = $hdrhash{"content-type"}{MAIN}; if ($contenttype eq "application/pkcs7-mime") { # # opaque-signed or enveloped message # unless (exists($hdrhash{"content-type"}{"smime-type"})) { print STDERR "ERROR: no smime-type attribute in application/pkcs7-smime entity.\n"; last; } $smimetype = $hdrhash{"content-type"}{"smime-type"}; if ($smimetype eq "signed-data" or $smimetype eq "enveloped-data") { # it's verification or decryption time! # can handle only base64 encoding for now # all other encodings are treated as binary (8bit) if ($hdrhash{"content-transfer-encoding"}{MAIN} eq "base64") { $mimebody = decode_base64($mimebody); } # if we need to dump the DER, we would do it right here # now write the DER $tmpderfile = "/tmp/der.$$"; open(TMP, ">$tmpderfile") or die "ERROR: cannot write signature data to temporary file"; print TMP $mimebody; unless (close(TMP)) { print STDERR "ERROR: writing signature data to temporary file.\n"; unlink($tmpderfile); exit 1; } $mimeheaders = ""; open(TMP, "$cmsutilpath -D $decodeopts -h $layercounter -i $tmpderfile |") or die "ERROR: cannot open pipe to cmsutil"; $layercounter++; while (<TMP>) { last if (/^\r?$/); # empty lines mark end of header if (/^SMIME: /) { # add all SMIME info to the rfc822 hdrs $lastref = \$rfc822headers; } elsif (/^\s/) { ; # continuation lines go to the last dest } else { $lastref = \$mimeheaders; # all other headers are mime headers } $$lastref .= $_; } # slurp in rest of the data to $mimebody $saveRS = $/; $/ = undef; $mimebody = <TMP>; $/ = $saveRS; close(TMP); unlink($tmpderfile); } else { print STDERR "ERROR: unknown smime-type \"$smimetype\" in application/pkcs7-smime entity.\n"; last; } } elsif ($contenttype eq "multipart/signed") { # # clear signed message # unless (exists($hdrhash{"content-type"}{"protocol"})) { print STDERR "ERROR: content type has no protocol attribute in multipart/signed entity.\n"; last; } if ($hdrhash{"content-type"}{"protocol"} ne "application/pkcs7-signature") { # we cannot handle this guy print STDERR "ERROR: unknown protocol \"", $hdrhash{"content-type"}{"protocol"}, "\" in multipart/signed entity.\n"; last; } unless (exists($hdrhash{"content-type"}{"boundary"})) { print STDERR "ERROR: no boundary attribute in multipart/signed entity.\n"; last; } $boundary = $hdrhash{"content-type"}{"boundary"}; # split $mimebody along \n--$boundary\n - gets you four parts # first (0), any comments the sending agent might have put in # second (1), the message itself # third (2), the signature as a mime entity # fourth (3), trailing data (there shouldn't be any) @multiparts = split(/\r?\n--$boundary(?:--)?\r?\n/, $mimebody); # # parse the signature headers ($submimeheaders, $submimebody) = split(/^$/m, $multiparts[2]); %sighdrhash = parseheaders($submimeheaders); unless (exists($sighdrhash{"content-type"}{MAIN})) { print STDERR "ERROR: signature entity has no content type.\n"; last; } if ($sighdrhash{"content-type"}{MAIN} ne "application/pkcs7-signature") { # we cannot handle this guy print STDERR "ERROR: unknown content type \"", $sighdrhash{"content-type"}{MAIN}, "\" in signature entity.\n"; last; } if ($sighdrhash{"content-transfer-encoding"}{MAIN} eq "base64") { $submimebody = decode_base64($submimebody); } # we would dump the DER at this point $tmpsigfile = "/tmp/sig.$$"; open(TMP, ">$tmpsigfile") or die "ERROR: cannot write signature data to temporary file"; print TMP $submimebody; unless (close(TMP)) { print STDERR "ERROR: writing signature data to temporary file.\n"; unlink($tmpsigfile); exit 1; } $tmpmsgfile = "/tmp/msg.$$"; open(TMP, ">$tmpmsgfile") or die "ERROR: cannot write message data to temporary file"; print TMP $multiparts[1]; unless (close(TMP)) { print STDERR "ERROR: writing message data to temporary file.\n"; unlink($tmpsigfile); unlink($tmpmsgfile); exit 1; } $mimeheaders = ""; open(TMP, "$cmsutilpath -D $decodeopts -h $layercounter -c $tmpmsgfile -i $tmpsigfile |") or die "ERROR: cannot open pipe to cmsutil"; $layercounter++; while (<TMP>) { last if (/^\r?$/); if (/^SMIME: /) { $lastref = \$rfc822headers; } elsif (/^\s/) { ; } else { $lastref = \$mimeheaders; } $$lastref .= $_; } $saveRS = $/; $/ = undef; $mimebody = <TMP>; $/ = $saveRS; close(TMP); unlink($tmpsigfile); unlink($tmpmsgfile); } else { # not a content type we know - we're done last; } } # so now we have the S/MIME parsing information in rfc822headers # and the first mime entity we could not handle in mimeheaders and mimebody. # dump 'em out and we're done. print $rfc822headers; print $mimeheaders . "\n" . $mimebody;} else { # # encode (which is much easier than decode) # $mimeentity = $mimeheaders . "\n" . $mimebody; # # canonicalize inner entity (rudimentary yet) # convert single LFs to CRLF # if no Content-Transfer-Encoding header present: # if 8 bit chars present, use Content-Transfer-Encoding: quoted-printable # otherwise, use Content-Transfer-Encoding: 7bit # $mimeentity =~ s/\r*\n/\r\n/mg; # # now do the wrapping # we sign first, then encrypt because that's what Communicator needs # if (defined($opt_S)) { $mimeentity = signentity($mimeentity, $signopts); } if (defined($opt_E)) { $mimeentity = encryptentity($mimeentity, $encryptopts); } # # XXX sign again to do triple wrapping (RFC2634) # # # now write out the RFC822 headers # followed by the final $mimeentity # print $rfc822headers; print "MIME-Version: 1.0 (NSS SMIME - http://www.mozilla.org/projects/security)\n"; # set up the flag print $mimeentity;}exit 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?