/* * * Copyright (c) 2013 - 2017 Lijun Liao * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License version 3 * as published by the Free Software Foundation with the addition of the * following permission added to Section 15 as permitted in Section 7(a): * * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY * THE AUTHOR LIJUN LIAO. LIJUN LIAO DISCLAIMS THE WARRANTY OF NON INFRINGEMENT * OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License. * * You can be released from the requirements of the license by purchasing * a commercial license. Buying such a license is mandatory as soon as you * develop commercial activities involving the XiPKI software without * disclosing the source code of your own applications. * * For more information, please contact Lijun Liao at this * address: lijun.liao@gmail.com */ package org.xipki.pki.ca.common.cmp; import java.util.Date; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.cmp.CMPObjectIdentifiers; import org.bouncycastle.asn1.cmp.InfoTypeAndValue; import org.bouncycastle.asn1.cmp.PKIFreeText; import org.bouncycastle.asn1.cmp.PKIHeader; import org.bouncycastle.asn1.cmp.PKIMessage; import org.bouncycastle.asn1.crmf.AttributeTypeAndValue; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.cmp.CMPException; import org.bouncycastle.cert.cmp.ProtectedPKIMessage; import org.bouncycastle.cert.cmp.ProtectedPKIMessageBuilder; import org.xipki.commons.common.util.ParamUtil; import org.xipki.commons.security.ConcurrentContentSigner; import org.xipki.commons.security.exception.NoIdleSignerException; /** * @author Lijun Liao * @since 2.0.0 */ public class CmpUtil { private CmpUtil() { } public static PKIMessage addProtection(final PKIMessage pkiMessage, final ConcurrentContentSigner signer, final GeneralName signerName) throws CMPException, NoIdleSignerException { return addProtection(pkiMessage, signer, signerName, true); } public static PKIMessage addProtection(final PKIMessage pkiMessage, final ConcurrentContentSigner signer, final GeneralName signerName, final boolean addSignerCert) throws CMPException, NoIdleSignerException { ParamUtil.requireNonNull("pkiMessage", pkiMessage); ParamUtil.requireNonNull("signer", signer); final GeneralName tmpSignerName; if (signerName != null) { tmpSignerName = signerName; } else { if (signer.getCertificate() == null) { throw new IllegalArgumentException("signer without certificate is not allowed"); } X500Name x500Name = X500Name.getInstance( signer.getCertificate().getSubjectX500Principal().getEncoded()); tmpSignerName = new GeneralName(x500Name); } PKIHeader header = pkiMessage.getHeader(); ProtectedPKIMessageBuilder builder = new ProtectedPKIMessageBuilder( tmpSignerName, header.getRecipient()); PKIFreeText freeText = header.getFreeText(); if (freeText != null) { builder.setFreeText(freeText); } InfoTypeAndValue[] generalInfo = header.getGeneralInfo(); if (generalInfo != null) { for (InfoTypeAndValue gi : generalInfo) { builder.addGeneralInfo(gi); } } ASN1OctetString octet = header.getRecipKID(); if (octet != null) { builder.setRecipKID(octet.getOctets()); } octet = header.getRecipNonce(); if (octet != null) { builder.setRecipNonce(octet.getOctets()); } octet = header.getSenderKID(); if (octet != null) { builder.setSenderKID(octet.getOctets()); } octet = header.getSenderNonce(); if (octet != null) { builder.setSenderNonce(octet.getOctets()); } octet = header.getTransactionID(); if (octet != null) { builder.setTransactionID(octet.getOctets()); } if (header.getMessageTime() != null) { builder.setMessageTime(new Date()); } builder.setBody(pkiMessage.getBody()); if (addSignerCert) { X509CertificateHolder signerCert = signer.getCertificateAsBcObject(); builder.addCMPCertificate(signerCert); } ProtectedPKIMessage signedMessage = signer.build(builder); return signedMessage.toASN1Structure(); } // method addProtection public static boolean isImplictConfirm(final PKIHeader header) { ParamUtil.requireNonNull("header", header); InfoTypeAndValue[] regInfos = header.getGeneralInfo(); if (regInfos == null) { return false; } for (InfoTypeAndValue regInfo : regInfos) { if (CMPObjectIdentifiers.it_implicitConfirm.equals(regInfo.getInfoType())) { return true; } } return false; } public static InfoTypeAndValue getImplictConfirmGeneralInfo() { return new InfoTypeAndValue(CMPObjectIdentifiers.it_implicitConfirm, DERNull.INSTANCE); } public static CmpUtf8Pairs extract(final InfoTypeAndValue[] regInfos) { if (regInfos == null) { return null; } for (InfoTypeAndValue regInfo : regInfos) { if (CMPObjectIdentifiers.regInfo_utf8Pairs.equals(regInfo.getInfoType())) { String regInfoValue = ((ASN1String) regInfo.getInfoValue()).getString(); return new CmpUtf8Pairs(regInfoValue); } } return null; } public static CmpUtf8Pairs extract(final AttributeTypeAndValue[] atvs) { if (atvs == null) { return null; } for (AttributeTypeAndValue atv : atvs) { if (CMPObjectIdentifiers.regInfo_utf8Pairs.equals(atv.getType())) { String regInfoValue = ((ASN1String) atv.getValue()).getString(); return new CmpUtf8Pairs(regInfoValue); } } return null; } public static InfoTypeAndValue buildInfoTypeAndValue(final CmpUtf8Pairs utf8Pairs) { ParamUtil.requireNonNull("utf8Pairs", utf8Pairs); return new InfoTypeAndValue(CMPObjectIdentifiers.regInfo_utf8Pairs, new DERUTF8String(utf8Pairs.getEncoded())); } public static AttributeTypeAndValue buildAttributeTypeAndValue(final CmpUtf8Pairs utf8Pairs) { ParamUtil.requireNonNull("utf8Pairs", utf8Pairs); return new AttributeTypeAndValue(CMPObjectIdentifiers.regInfo_utf8Pairs, new DERUTF8String(utf8Pairs.getEncoded())); } }