📄 sceprequestmessage.java
字号:
/************************************************************************* * * * EJBCA: The OpenSource Certificate Authority * * * * This software is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or any later version. * * * * See terms of license at gnu.org. * * * *************************************************************************/ package se.anatom.ejbca.protocol;import java.io.*;import java.math.BigInteger;import java.security.GeneralSecurityException;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.cert.X509Certificate;import java.util.Collection;import java.util.Enumeration;import java.util.Iterator;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import org.apache.log4j.Logger;import org.bouncycastle.asn1.*;import org.bouncycastle.asn1.cms.*;import org.bouncycastle.cms.*;import org.bouncycastle.jce.PKCS10CertificationRequest;import se.anatom.ejbca.util.Base64;import se.anatom.ejbca.util.CertTools;/** * Class to handle SCEP request messages sent to the CA. * TODO: don't forget extensions, e.g. KeyUsage requested by end entity * * @version $Id: ScepRequestMessage.java,v 1.33 2004/04/16 07:38:55 anatom Exp $ */public class ScepRequestMessage extends PKCS10RequestMessage implements IRequestMessage, Serializable { private static Logger log = Logger.getLogger(ScepRequestMessage.class); public static final String id_Verisign = "2.16.840.1.113733"; public static final String id_pki = id_Verisign + ".1"; public static final String id_attributes = id_pki + ".9"; public static final String id_messageType = id_attributes + ".2"; public static final String id_pkiStatus = id_attributes + ".3"; public static final String id_failInfo = id_attributes + ".4"; public static final String id_senderNonce = id_attributes + ".5"; public static final String id_recipientNonce = id_attributes + ".6"; public static final String id_transId = id_attributes + ".7"; public static final String id_extensionReq = id_attributes + ".8"; /** Raw form of the Scep message */ private byte[] scepmsg; /** * The messageType attribute specify the type of operation performed by the transaction. This * attribute is required in all PKI messages. Currently, the following message types are * defined: * PKCSReq (19) -- Permits use of PKCS#10 certificate request * CertRep (3) -- Response to certificate or CRL request * GetCertInitial (20) -- Certificate polling in manual enrollment * GetCert (21) -- Retrieve a certificate * GetCRL (22) -- Retrieve a CRL */ private int messageType = 0; public static int SCEP_TYPE_PKCSREQ = 19; public static int SCEP_TYPE_GETCRL = 22; public static int SCEP_TYPE_GETCERT = 21; /** * SenderNonce in a request is used as recipientNonce when the server sends back a reply to the * client. This is base64 encoded bytes */ private String senderNonce = null; /** transaction id */ private String transactionId = null; /** request key info, this is the requestors self-signed certificate used to identify the senders public key */ private byte[] requestKeyInfo = null; /** Type of error */ private int error = 0; /** Error text */ private String errorText = null; /** Issuer DN the message is sent to (CAs DN), contained in the * request as recipientInfo.issuerAndSerialNumber in EnvelopeData part */ private transient String issuerDN = null; /** Signed data, the whole enchilada to to speak... */ private transient SignedData sd = null; /** Enveloped data, carrying the 'beef' of the request */ private transient EnvelopedData envData = null; /** Enveloped data, carrying the 'beef' of the request */ private transient ContentInfo envEncData = null; /** Private key used for decryption. */ private transient PrivateKey privateKey = null; /** IssuerAndSerialNUmber for CRL request */ private transient IssuerAndSerialNumber issuerAndSerno = null; /** * Constucts a new SCEP/PKCS7 message handler object. * * @param msg The DER encoded PKCS7 request. * * @throws IOException if the request can not be parsed. */ public ScepRequestMessage(byte[] msg) throws IOException, InvalidKeyException, GeneralSecurityException, CMSException { log.debug(">ScepRequestMessage"); this.scepmsg = msg; init(); log.debug("<ScepRequestMessage"); } private void init() throws IOException { log.debug(">init"); // Parse and verify the entegrity of the PKIOperation message PKCS#7 /* If this would have been done using the newer CMS it would have made me so much happier... */ ASN1Sequence seq = (ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream(scepmsg)).readObject(); ContentInfo ci = new ContentInfo(seq); String ctoid = ci.getContentType().getId(); if (ctoid.equals(CMSObjectIdentifiers.signedData.getId())) { // This is SignedData so it is a pkcsCertReqSigned, // pkcsGetCertInitialSigned, pkcsGetCertSigned, pkcsGetCRLSigned // (could also be pkcsRepSigned or certOnly, but we don't receive them on the server side // Try to find out what kind of message this is sd = new SignedData((ASN1Sequence) ci.getContent()); // Get self signed cert to identify the senders public key ASN1Set certs = sd.getCertificates(); if (certs.size() > 0) { // There should be only one... DEREncodable dercert = certs.getObjectAt(0); if (dercert != null) { // Requestors self-signed certificate is requestKeyInfo ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(dercert); if (bOut.size() > 0 ) { requestKeyInfo = bOut.toByteArray(); } } } Enumeration sis = sd.getSignerInfos().getObjects(); if (sis.hasMoreElements()) { SignerInfo si = new SignerInfo((ASN1Sequence) sis.nextElement()); Enumeration attr = si.getAuthenticatedAttributes().getObjects(); while (attr.hasMoreElements()) { Attribute a = new Attribute((ASN1Sequence) attr.nextElement()); log.debug("Found attribute: " + a.getAttrType().getId()); if (a.getAttrType().getId().equals(id_senderNonce)) { Enumeration values = a.getAttrValues().getObjects(); ASN1OctetString str = ASN1OctetString.getInstance(values.nextElement()); senderNonce = new String(Base64.encode(str.getOctets(),false)); log.debug("senderNonce = " + senderNonce); } if (a.getAttrType().getId().equals(id_transId)) { Enumeration values = a.getAttrValues().getObjects(); DERPrintableString str = DERPrintableString.getInstance(values.nextElement()); transactionId = str.getString(); log.debug("transactionId = " + transactionId); } if (a.getAttrType().getId().equals(id_messageType)) { Enumeration values = a.getAttrValues().getObjects(); DERPrintableString str = DERPrintableString.getInstance(values.nextElement()); messageType = Integer.parseInt(str.getString()); log.debug("messagetype = " + messageType); } } } // If this is a PKCSReq if ( (messageType == ScepRequestMessage.SCEP_TYPE_PKCSREQ) || (messageType == ScepRequestMessage.SCEP_TYPE_GETCRL) ) { // Extract the contents, which is an encrypted PKCS10 if messageType == 19 // and an encrypted IssuerAndSerialNumber if messageType == 22 ci = sd.getEncapContentInfo(); ctoid = ci.getContentType().getId(); if (ctoid.equals(CMSObjectIdentifiers.data.getId())) { DEROctetString content = (DEROctetString) ci.getContent(); log.debug("envelopedData is " + content.getOctets().length + " bytes."); ASN1Sequence seq1 = (ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream( content.getOctets())).readObject(); envEncData = new ContentInfo(seq1); ctoid = envEncData.getContentType().getId(); if (ctoid.equals(CMSObjectIdentifiers.envelopedData.getId())) { envData = new EnvelopedData((ASN1Sequence) envEncData.getContent()); ASN1Set recipientInfos = envData.getRecipientInfos(); Enumeration e = recipientInfos.getObjects(); while (e.hasMoreElements()) { RecipientInfo ri = RecipientInfo.getInstance(e.nextElement()); KeyTransRecipientInfo recipientInfo = KeyTransRecipientInfo.getInstance(ri.getInfo()); RecipientIdentifier rid = recipientInfo.getRecipientIdentifier(); IssuerAndSerialNumber iasn = IssuerAndSerialNumber.getInstance(rid.getId()); issuerDN = iasn.getName().toString(); log.debug("IssuerDN: "+issuerDN); } } else { errorText = "EncapsulatedContentInfo does not contain PKCS7 envelopedData: "; log.error(errorText + ctoid); error = 2; } } else { errorText = "EncapsulatedContentInfo is not of type 'data': "; log.error(errorText + ctoid); error = 3; } } else { errorText = "This is not a certification request!"; log.error(errorText); error = 4; } } else { errorText = "PKCSReq does not contain 'signedData': "; log.error(errorText + ctoid); error = 1; } log.debug("<init"); } // init private void decrypt() throws NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, CMSException, NoSuchProviderException, BadPaddingException, InvalidAlgorithmParameterException, GeneralSecurityException, IOException { log.debug(">decrypt"); // Now we are getting somewhere (pheew), // Now we just have to get the damn key...to decrypt the PKCS10 if (privateKey == null) { errorText = "Need private key to decrypt!"; error = 5; log.error(errorText); return; } if (envEncData == null) { errorText = "No enveloped data to decrypt!"; error = 6; log.error(errorText); return; } CMSEnvelopedData ed = new CMSEnvelopedData(envEncData); RecipientInformationStore recipients = ed.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); byte[] decBytes = null; while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation) it.next(); decBytes = recipient.getContent(privateKey, "BC"); break; } DERObject derobj = new DERInputStream(new ByteArrayInputStream(decBytes)).readObject(); if (messageType == ScepRequestMessage.SCEP_TYPE_PKCSREQ) { ASN1Sequence seq = (ASN1Sequence)derobj; pkcs10 = new PKCS10CertificationRequest(seq); } if (messageType == ScepRequestMessage.SCEP_TYPE_GETCRL) { issuerAndSerno = IssuerAndSerialNumber.getInstance(derobj); } log.debug("Successfully extracted PKCS10."); log.debug("<decrypt"); } // decrypt /** * Returns the public key from the certificattion request. * * @return public key from certification request. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -