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 + -
显示快捷键?