Example usage for java.security KeyPair getPrivate

List of usage examples for java.security KeyPair getPrivate

Introduction

In this page you can find the example usage for java.security KeyPair getPrivate.

Prototype

public PrivateKey getPrivate() 

Source Link

Document

Returns a reference to the private key component of this key pair.

Usage

From source file:org.globus.myproxy.MyProxy.java

/**
 * Retrieves delegated credentials from the MyProxy server.
 *
 * @param  credential/*from  w  w  w  . jav  a  2s. c  om*/
 *         The local GSI credentials to use for authentication.
 *         Can be set to null if no local credentials.
 * @param  params
 *         The parameters for the get operation.
 * @return GSSCredential
 *         The retrieved delegated credentials.
 * @exception MyProxyException
 *         If an error occurred during the operation.
 */
public GSSCredential get(GSSCredential credential, GetParams params) throws MyProxyException {

    if (params == null) {
        throw new IllegalArgumentException("params == null");
    }

    if (credential == null) {
        try {
            credential = getAnonymousCredential();
        } catch (GSSException e) {
            throw new MyProxyException("Failed to create anonymous credentials", e);
        }
    }

    String msg = params.makeRequest();

    Socket gsiSocket = null;
    OutputStream out = null;
    InputStream in = null;

    try {
        gsiSocket = getSocket(credential);

        if (credential.getName().isAnonymous()) {
            this.context.requestAnonymity(true);
        }

        out = gsiSocket.getOutputStream();
        in = gsiSocket.getInputStream();

        if (!((GssSocket) gsiSocket).getContext().getConfState())
            throw new Exception("Confidentiality requested but not available");

        // send message
        out.write(msg.getBytes());
        out.flush();

        if (logger.isDebugEnabled()) {
            logger.debug("Req sent:" + params);
        }

        // may require authz handshake
        handleReply(in, out, params.getAuthzCreds(), params.getWantTrustroots());

        // start delegation - generate key pair
        KeyPair keyPair = CertificateUtil.generateKeyPair("RSA", DEFAULT_KEYBITS);

        // According to the MyProxy protocol, the MyProxy server
        // will ignore the subject in the client's certificate
        // signing request (CSR). However, in some cases it is
        // helpful to control the CSR subject (for example, when
        // the MyProxy server is using a CA back-end that can only
        // issue certificates with subjects matching the request).
        // So we construct the CSR subject using the given MyProxy
        // username (if possible).
        String CSRsubjectString = params.getUserName();
        CSRsubjectString = CSRsubjectString.trim();
        if (CSRsubjectString.contains("CN=") || CSRsubjectString.contains("cn=")) {
            // If the MyProxy username is a DN, use it.
            if (CSRsubjectString.charAt(0) == '/') {
                // "good enough" conversion of OpenSSL DN strings
                CSRsubjectString = CSRsubjectString.substring(1);
                CSRsubjectString = CSRsubjectString.replace('/', ',');
            }
        } else {
            CSRsubjectString = "CN=" + CSRsubjectString;
        }

        X509Name CSRsubjectName;
        try {
            CSRsubjectName = new X509Name(CSRsubjectString);
        } catch (Exception e) {
            // If our X509Name construction fails for any reason,
            // just use a default value (as in the past).
            CSRsubjectName = new X509Name("CN=ignore");
        }

        if (logger.isDebugEnabled()) {
            logger.debug("CSR subject: " + CSRsubjectName.toString());
        }

        BouncyCastleCertProcessingFactory certFactory = BouncyCastleCertProcessingFactory.getDefault();

        byte[] req = null;
        req = certFactory.createCertificateRequest(CSRsubjectName, "SHA1WithRSAEncryption", keyPair);

        // send the request to server
        out.write(req);
        out.flush();

        // read the number of certificates
        int size = in.read();

        if (logger.isDebugEnabled()) {
            logger.debug("Reading " + size + " certs");
        }

        X509Certificate[] chain = new X509Certificate[size];

        for (int i = 0; i < size; i++) {
            chain[i] = certFactory.loadCertificate(in);
            // DEBUG: display the cert names
            if (logger.isDebugEnabled()) {
                logger.debug("Received cert: " + chain[i].getSubjectDN());
            }
        }

        // get the response
        handleReply(in);

        // make sure the private key belongs to the right public key
        // currently only works with RSA keys
        RSAPublicKey pkey = (RSAPublicKey) chain[0].getPublicKey();
        RSAPrivateKey prkey = (RSAPrivateKey) keyPair.getPrivate();

        if (!pkey.getModulus().equals(prkey.getModulus())) {
            throw new MyProxyException("Private/Public key mismatch!");
        }

        X509Credential newCredential = null;

        newCredential = new X509Credential(keyPair.getPrivate(), chain);

        return new GlobusGSSCredentialImpl(newCredential, GSSCredential.INITIATE_AND_ACCEPT);

    } catch (Exception e) {
        throw new MyProxyException("MyProxy get failed.", e);
    } finally {
        // close socket
        close(out, in, gsiSocket);
    }
}

From source file:org.alfresco.extension.countersign.signature.RepositoryManagedSignatureProvider.java

/**
 * Generate an X509 cert for use as the keystore cert chain
 * //from  ww w  .  j  ava  2  s .  co  m
 * @param keyPair
 * @return
 */
private X509Certificate generateCertificate(KeyPair keyPair, NodeRef person) {

    X509Certificate cert = null;
    int validDuration = Integer
            .parseInt(config.getProperty(RepositoryManagedSignatureProviderFactory.VALID_DURATION));

    // get user's first and last name
    Map<QName, Serializable> props = serviceRegistry.getNodeService().getProperties(person);
    String firstName = String.valueOf(props.get(ContentModel.PROP_FIRSTNAME));
    String lastName = String.valueOf(props.get(ContentModel.PROP_LASTNAME));

    // backdate the start date by a day
    Calendar start = Calendar.getInstance();
    start.add(Calendar.DATE, -1);
    java.util.Date startDate = start.getTime();

    // what is the end date for this cert's validity?
    Calendar end = Calendar.getInstance();
    end.add(Calendar.DATE, validDuration);
    java.util.Date endDate = end.getTime();

    try {
        // This code works with newer versions of the BouncyCastle libraries, but not
        // the (severely outdated) version that ships with Alfresco
        /*X509v1CertificateBuilder certBuilder = new JcaX509v1CertificateBuilder(
            new X500Principal("CN=" + firstName + " " + lastName), 
            BigInteger.ONE, 
            startDate, cal.getTime(), 
            new X500Principal("CN=" + firstName + " " + lastName), 
            keyPair.getPublic());
                
         AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA");
         AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);
         AsymmetricKeyParameter keyParam = PrivateKeyFactory.createKey(keyPair.getPrivate().getEncoded());
        ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId).build(keyParam);
        X509CertificateHolder certHolder = certBuilder.build(sigGen);
                
        // now lets convert this thing back to a regular old java cert
        CertificateFactory cf = CertificateFactory.getInstance("X.509");  
         InputStream certIs = new ByteArrayInputStream(certHolder.getEncoded()); 
         cert = (X509Certificate) cf.generateCertificate(certIs); 
         certIs.close();*/

        X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
        X500Principal subjectName = new X500Principal("CN=" + firstName + " " + lastName);

        certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
        certGen.setNotBefore(startDate);
        certGen.setNotAfter(endDate);
        certGen.setSubjectDN(subjectName);
        certGen.setPublicKey(keyPair.getPublic());
        certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");

        // if we are actually generating a trusted cert, the action is a little different
        boolean generateTrusted = Boolean.parseBoolean(
                config.getProperty(RepositoryManagedSignatureProviderFactory.ENABLE_TRUSTED_CERTS));
        if (generateTrusted) {
            KeyStore trustedKs = getTrustedKeyStore();

            PrivateKey caKey = getCaKey(trustedKs);
            X509Certificate caCert = getCaCert(trustedKs);

            // set the issuer of the generated cert to the subject of the ca cert
            X500Principal caSubject = caCert.getSubjectX500Principal();
            certGen.setIssuerDN(caSubject);

            //add the required extensions for the new cert
            certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
                    new AuthorityKeyIdentifierStructure(caCert));
            certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
                    new SubjectKeyIdentifierStructure(keyPair.getPublic()));

            cert = certGen.generate(caKey, "BC");

            //verify the cert
            cert.verify(caCert.getPublicKey());
        } else {
            certGen.setIssuerDN(subjectName);
            cert = certGen.generate(keyPair.getPrivate(), "BC");
        }
    } catch (CertificateException ce) {
        logger.error("CertificateException creating or validating X509 certificate for user: " + ce);
        throw new AlfrescoRuntimeException(ce.getMessage());
    } catch (Exception ex) {
        logger.error("Unknown exception creating or validating X509 certificate for user : " + ex);
        ex.printStackTrace();
    }

    return cert;
}

From source file:com.netscape.cms.servlet.csadmin.ConfigurationUtils.java

public static KeyPair createECCKeyPair(String token, String curveName, IConfigStore config, String ct)
        throws NoSuchAlgorithmException, NoSuchTokenException, TokenException, NotInitializedException,
        EPropertyNotFound, EBaseException {

    logger.debug("ConfigurationUtils.createECCKeyPair(" + token + ", " + curveName + ")");

    KeyPair pair = null;
    /*// w w w. j ava2  s.c  om
     * default ssl server cert to ECDHE unless stated otherwise
     * note: IE only supports "ECDHE", but "ECDH" is more efficient
     *
     * for "ECDHE", server.xml should have the following for ciphers:
     * +TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
     * -TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
     *
     * for "ECDH", server.xml should have the following for ciphers:
     * -TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
     * +TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
     */
    String sslType = "ECDHE";
    try {
        sslType = config.getString(PCERT_PREFIX + ct + "ec.type", "ECDHE");
    } catch (Exception e) {
    }

    // ECDHE needs "SIGN" but no "DERIVE"
    org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask[] = {
            org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.DERIVE };

    // ECDH needs "DERIVE" but no any kind of "SIGN"
    org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage ECDH_usages_mask[] = {
            org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN,
            org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN_RECOVER, };

    do {
        if (ct.equals("sslserver") && sslType.equalsIgnoreCase("ECDH")) {
            logger.debug(
                    "ConfigurationUtils: createECCKeypair: sslserver cert for ECDH. Make sure server.xml is set "
                            + "properly with -TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,+TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
            pair = CryptoUtil.generateECCKeyPair(token, curveName, null, ECDH_usages_mask);
        } else {
            if (ct.equals("sslserver")) {
                logger.debug(
                        "ConfigurationUtils: createECCKeypair: sslserver cert for ECDHE. Make sure server.xml is set "
                                + "properly with +TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
            }
            pair = CryptoUtil.generateECCKeyPair(token, curveName, null, usages_mask);
        }

        // XXX - store curve , w
        byte id[] = ((org.mozilla.jss.crypto.PrivateKey) pair.getPrivate()).getUniqueID();
        String kid = CryptoUtil.encodeKeyID(id);

        // try to locate the private key
        org.mozilla.jss.crypto.PrivateKey privk = CryptoUtil.findPrivateKeyFromID(CryptoUtil.decodeKeyID(kid));
        if (privk == null) {
            logger.debug("Found bad ECC key id " + kid);
            pair = null;
        }
    } while (pair == null);

    return pair;
}

From source file:org.ejbca.ui.cmpclient.commands.CrmfRequestCommand.java

@Override
public PKIMessage generatePKIMessage(final ParameterContainer parameters) throws Exception {

    final boolean verbose = parameters.containsKey(VERBOSE_KEY);

    final X500Name userDN = new X500Name(parameters.get(SUBJECTDN_KEY));
    final X500Name issuerDN = new X500Name(parameters.get(ISSUERDN_KEY));

    String authmodule = parameters.get(AUTHENTICATION_MODULE_KEY);
    String endentityPassword = "";
    if (authmodule != null && StringUtils.equals(authmodule, CmpConfiguration.AUTHMODULE_REG_TOKEN_PWD)) {
        endentityPassword = parameters.containsKey(AUTHENTICATION_PARAM_KEY)
                ? parameters.get(AUTHENTICATION_PARAM_KEY)
                : "foo123";
    }//w ww  . jav  a  2s . c  om

    String altNames = parameters.get(ALTNAME_KEY);
    String serno = parameters.get(SERNO_KEY);
    BigInteger customCertSerno = null;
    if (serno != null) {
        customCertSerno = new BigInteger(serno, 16);
    }
    boolean includePopo = parameters.containsKey(INCLUDE_POPO_KEY);

    if (verbose) {
        log.info("Creating CRMF request with: SubjectDN=" + userDN.toString());
        log.info("Creating CRMF request with: IssuerDN=" + issuerDN.toString());
        log.info("Creating CRMF request with: AuthenticationModule=" + authmodule);
        log.info("Creating CRMF request with: EndEntityPassword=" + endentityPassword);
        log.info("Creating CRMF request with: SubjectAltName=" + altNames);
        log.info("Creating CRMF request with: CustomCertSerno="
                + (customCertSerno == null ? "" : customCertSerno.toString(16)));
        log.info("Creating CRMF request with: IncludePopo=" + includePopo);
    }

    final KeyPair keys = KeyTools.genKeys("1024", AlgorithmConstants.KEYALGORITHM_RSA);
    final byte[] nonce = CmpClientMessageHelper.getInstance().createSenderNonce();
    final byte[] transid = CmpClientMessageHelper.getInstance().createSenderNonce();

    // We should be able to back date the start time when allow validity
    // override is enabled in the certificate profile
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.DAY_OF_WEEK, -1);
    cal.set(Calendar.MILLISECOND, 0); // Certificates don't use milliseconds
    // in validity
    Date notBefore = cal.getTime();
    cal.add(Calendar.DAY_OF_WEEK, 3);
    cal.set(Calendar.MILLISECOND, 0); // Certificates don't use milliseconds
    org.bouncycastle.asn1.x509.Time nb = new org.bouncycastle.asn1.x509.Time(notBefore);
    // in validity
    Date notAfter = cal.getTime();
    org.bouncycastle.asn1.x509.Time na = new org.bouncycastle.asn1.x509.Time(notAfter);

    ASN1EncodableVector optionalValidityV = new ASN1EncodableVector();
    optionalValidityV.add(new DERTaggedObject(true, 0, nb));
    optionalValidityV.add(new DERTaggedObject(true, 1, na));
    OptionalValidity myOptionalValidity = OptionalValidity.getInstance(new DERSequence(optionalValidityV));

    CertTemplateBuilder myCertTemplate = new CertTemplateBuilder();
    myCertTemplate.setValidity(myOptionalValidity);
    if (issuerDN != null) {
        myCertTemplate.setIssuer(issuerDN);
    }
    myCertTemplate.setSubject(userDN);
    byte[] bytes = keys.getPublic().getEncoded();
    ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);
    ASN1InputStream dIn = new ASN1InputStream(bIn);
    SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo((ASN1Sequence) dIn.readObject());
    dIn.close();
    myCertTemplate.setPublicKey(keyInfo);

    // Create standard extensions
    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    ASN1OutputStream dOut = new ASN1OutputStream(bOut);
    ExtensionsGenerator extgen = new ExtensionsGenerator();
    if (altNames != null) {
        GeneralNames san = CertTools.getGeneralNamesFromAltName(altNames);
        dOut.writeObject(san);
        byte[] value = bOut.toByteArray();
        extgen.addExtension(Extension.subjectAlternativeName, false, value);
    }

    // KeyUsage
    int bcku = 0;
    bcku = KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.nonRepudiation;
    KeyUsage ku = new KeyUsage(bcku);
    extgen.addExtension(Extension.keyUsage, false, new DERBitString(ku));

    // Make the complete extension package
    Extensions exts = extgen.generate();

    myCertTemplate.setExtensions(exts);
    if (customCertSerno != null) {
        // Add serialNumber to the certTemplate, it is defined as a MUST NOT be used in RFC4211, but we will use it anyway in order
        // to request a custom certificate serial number (something not standard anyway)
        myCertTemplate.setSerialNumber(new ASN1Integer(customCertSerno));
    }

    CertRequest myCertRequest = new CertRequest(4, myCertTemplate.build(), null);

    // POPO
    /*
     * PKMACValue myPKMACValue = new PKMACValue( new AlgorithmIdentifier(new
     * ASN1ObjectIdentifier("8.2.1.2.3.4"), new DERBitString(new byte[] { 8,
     * 1, 1, 2 })), new DERBitString(new byte[] { 12, 29, 37, 43 }));
     * 
     * POPOPrivKey myPOPOPrivKey = new POPOPrivKey(new DERBitString(new
     * byte[] { 44 }), 2); //take choice pos tag 2
     * 
     * POPOSigningKeyInput myPOPOSigningKeyInput = new POPOSigningKeyInput(
     * myPKMACValue, new SubjectPublicKeyInfo( new AlgorithmIdentifier(new
     * ASN1ObjectIdentifier("9.3.3.9.2.2"), new DERBitString(new byte[] { 2,
     * 9, 7, 3 })), new byte[] { 7, 7, 7, 4, 5, 6, 7, 7, 7 }));
     */
    ProofOfPossession myProofOfPossession = null;
    if (includePopo) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DEROutputStream mout = new DEROutputStream(baos);
        mout.writeObject(myCertRequest);
        mout.close();
        byte[] popoProtectionBytes = baos.toByteArray();
        String sigalg = AlgorithmTools.getSignAlgOidFromDigestAndKey(null, keys.getPrivate().getAlgorithm())
                .getId();
        Signature sig = Signature.getInstance(sigalg, "BC");
        sig.initSign(keys.getPrivate());
        sig.update(popoProtectionBytes);
        DERBitString bs = new DERBitString(sig.sign());
        POPOSigningKey myPOPOSigningKey = new POPOSigningKey(null,
                new AlgorithmIdentifier(new ASN1ObjectIdentifier(sigalg)), bs);
        myProofOfPossession = new ProofOfPossession(myPOPOSigningKey);
    } else {
        // raVerified POPO (meaning there is no POPO)
        myProofOfPossession = new ProofOfPossession();
    }

    AttributeTypeAndValue av = new AttributeTypeAndValue(CRMFObjectIdentifiers.id_regCtrl_regToken,
            new DERUTF8String(endentityPassword));
    AttributeTypeAndValue[] avs = { av };

    CertReqMsg myCertReqMsg = new CertReqMsg(myCertRequest, myProofOfPossession, avs);

    CertReqMessages myCertReqMessages = new CertReqMessages(myCertReqMsg);

    PKIHeaderBuilder myPKIHeader = new PKIHeaderBuilder(2, new GeneralName(userDN), new GeneralName(issuerDN));

    myPKIHeader.setMessageTime(new ASN1GeneralizedTime(new Date()));
    // senderNonce
    myPKIHeader.setSenderNonce(new DEROctetString(nonce));
    // TransactionId
    myPKIHeader.setTransactionID(new DEROctetString(transid));
    myPKIHeader.setProtectionAlg(null);
    myPKIHeader.setSenderKID(new byte[0]);

    PKIBody myPKIBody = new PKIBody(0, myCertReqMessages); // initialization
    // request
    PKIMessage myPKIMessage = new PKIMessage(myPKIHeader.build(), myPKIBody);

    return myPKIMessage;
}

From source file:org.ejbca.core.protocol.cmp.CmpTestCase.java

protected static PKIMessage genCertReq(String issuerDN, X500Name userDN, String altNames, KeyPair keys,
        Certificate cacert, byte[] nonce, byte[] transid, boolean raVerifiedPopo, Extensions extensions,
        Date notBefore, Date notAfter, BigInteger customCertSerno, AlgorithmIdentifier pAlg,
        DEROctetString senderKID) throws NoSuchAlgorithmException, NoSuchProviderException, IOException,
        InvalidKeyException, SignatureException {
    ASN1EncodableVector optionalValidityV = new ASN1EncodableVector();
    org.bouncycastle.asn1.x509.Time nb = new org.bouncycastle.asn1.x509.Time(
            new DERGeneralizedTime("20030211002120Z"));
    if (notBefore != null) {
        nb = new org.bouncycastle.asn1.x509.Time(notBefore);
    }//w w  w  .  j av a  2  s.c  o m
    optionalValidityV.add(new DERTaggedObject(true, 0, nb));
    org.bouncycastle.asn1.x509.Time na = new org.bouncycastle.asn1.x509.Time(new Date());
    if (notAfter != null) {
        na = new org.bouncycastle.asn1.x509.Time(notAfter);
    }
    optionalValidityV.add(new DERTaggedObject(true, 1, na));
    OptionalValidity myOptionalValidity = OptionalValidity.getInstance(new DERSequence(optionalValidityV));

    CertTemplateBuilder myCertTemplate = new CertTemplateBuilder();
    myCertTemplate.setValidity(myOptionalValidity);
    if (issuerDN != null) {
        myCertTemplate.setIssuer(new X500Name(issuerDN));
    }
    myCertTemplate.setSubject(userDN);
    byte[] bytes = keys.getPublic().getEncoded();
    ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);
    ASN1InputStream dIn = new ASN1InputStream(bIn);
    SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo((ASN1Sequence) dIn.readObject());
    dIn.close();
    myCertTemplate.setPublicKey(keyInfo);
    // If we did not pass any extensions as parameter, we will create some of our own, standard ones
    Extensions exts = extensions;
    if (exts == null) {

        // SubjectAltName
        // Some altNames
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        ASN1OutputStream dOut = new ASN1OutputStream(bOut);
        ExtensionsGenerator extgen = new ExtensionsGenerator();
        if (altNames != null) {
            GeneralNames san = CertTools.getGeneralNamesFromAltName(altNames);
            dOut.writeObject(san);
            byte[] value = bOut.toByteArray();
            extgen.addExtension(Extension.subjectAlternativeName, false, value);
        }

        // KeyUsage
        int bcku = 0;
        bcku = KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.nonRepudiation;
        KeyUsage ku = new KeyUsage(bcku);
        extgen.addExtension(Extension.keyUsage, false, new DERBitString(ku));

        // Make the complete extension package
        exts = extgen.generate();
    }
    myCertTemplate.setExtensions(exts);
    if (customCertSerno != null) {
        // Add serialNumber to the certTemplate, it is defined as a MUST NOT be used in RFC4211, but we will use it anyway in order
        // to request a custom certificate serial number (something not standard anyway)
        myCertTemplate.setSerialNumber(new ASN1Integer(customCertSerno));
    }

    CertRequest myCertRequest = new CertRequest(4, myCertTemplate.build(), null);

    // POPO
    /*
     * PKMACValue myPKMACValue = new PKMACValue( new AlgorithmIdentifier(new
     * ASN1ObjectIdentifier("8.2.1.2.3.4"), new DERBitString(new byte[] { 8,
     * 1, 1, 2 })), new DERBitString(new byte[] { 12, 29, 37, 43 }));
     * 
     * POPOPrivKey myPOPOPrivKey = new POPOPrivKey(new DERBitString(new
     * byte[] { 44 }), 2); //take choice pos tag 2
     * 
     * POPOSigningKeyInput myPOPOSigningKeyInput = new POPOSigningKeyInput(
     * myPKMACValue, new SubjectPublicKeyInfo( new AlgorithmIdentifier(new
     * ASN1ObjectIdentifier("9.3.3.9.2.2"), new DERBitString(new byte[] { 2,
     * 9, 7, 3 })), new byte[] { 7, 7, 7, 4, 5, 6, 7, 7, 7 }));
     */
    ProofOfPossession myProofOfPossession = null;
    if (raVerifiedPopo) {
        // raVerified POPO (meaning there is no POPO)
        myProofOfPossession = new ProofOfPossession();
    } else {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DEROutputStream mout = new DEROutputStream(baos);
        mout.writeObject(myCertRequest);
        mout.close();
        byte[] popoProtectionBytes = baos.toByteArray();
        String sigalg = AlgorithmTools.getSignAlgOidFromDigestAndKey(null, keys.getPrivate().getAlgorithm())
                .getId();
        Signature sig = Signature.getInstance(sigalg, "BC");
        sig.initSign(keys.getPrivate());
        sig.update(popoProtectionBytes);
        DERBitString bs = new DERBitString(sig.sign());
        POPOSigningKey myPOPOSigningKey = new POPOSigningKey(null,
                new AlgorithmIdentifier(new ASN1ObjectIdentifier(sigalg)), bs);
        myProofOfPossession = new ProofOfPossession(myPOPOSigningKey);
    }

    AttributeTypeAndValue av = new AttributeTypeAndValue(CRMFObjectIdentifiers.id_regCtrl_regToken,
            new DERUTF8String("foo123"));
    AttributeTypeAndValue[] avs = { av };

    CertReqMsg myCertReqMsg = new CertReqMsg(myCertRequest, myProofOfPossession, avs);

    CertReqMessages myCertReqMessages = new CertReqMessages(myCertReqMsg);

    PKIHeaderBuilder myPKIHeader = new PKIHeaderBuilder(2, new GeneralName(userDN), new GeneralName(
            new X500Name(issuerDN != null ? issuerDN : ((X509Certificate) cacert).getSubjectDN().getName())));

    myPKIHeader.setMessageTime(new ASN1GeneralizedTime(new Date()));
    // senderNonce
    myPKIHeader.setSenderNonce(new DEROctetString(nonce));
    // TransactionId
    myPKIHeader.setTransactionID(new DEROctetString(transid));
    myPKIHeader.setProtectionAlg(pAlg);
    myPKIHeader.setSenderKID(senderKID);

    PKIBody myPKIBody = new PKIBody(0, myCertReqMessages); // initialization
                                                           // request
    PKIMessage myPKIMessage = new PKIMessage(myPKIHeader.build(), myPKIBody);
    return myPKIMessage;
}

From source file:org.ejbca.core.protocol.ws.EjbcaWS.java

@Override
public List<TokenCertificateResponseWS> genTokenCertificates(UserDataVOWS userDataWS,
        List<TokenCertificateRequestWS> tokenRequests, HardTokenDataWS hardTokenDataWS,
        boolean overwriteExistingSN, boolean revokePreviousCards)
        throws CADoesntExistsException, AuthorizationDeniedException, WaitingForApprovalException,
        HardTokenExistsException, UserDoesntFullfillEndEntityProfile, ApprovalException, EjbcaException,
        ApprovalRequestExpiredException, ApprovalRequestExecutionException {
    final ArrayList<TokenCertificateResponseWS> retval = new ArrayList<TokenCertificateResponseWS>();

    final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession,
            caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession,
            endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession,
            cryptoTokenManagementSession);
    AuthenticationToken admin = ejbhelper.getAdmin(true);
    int endEntityProfileId = 0;
    boolean hardTokenExists = false;
    boolean userExists = false;

    boolean approvalSuccessfullStep1 = false;
    boolean isRejectedStep1 = false;

    // Get Significant user Id
    final CAInfo significantcAInfo;
    final ArrayList<java.security.cert.Certificate> genCertificates = new ArrayList<java.security.cert.Certificate>();
    final IPatternLogger logger = TransactionLogger.getPatternLogger();
    logAdminName(admin, logger);/* ww  w. ja v a  2  s  .  c o m*/
    final AuthenticationToken intAdmin = new AlwaysAllowLocalAuthenticationToken(
            new UsernamePrincipal("EJBCAWS.genTokenCertificates"));
    try {
        significantcAInfo = caSession.getCAInfo(intAdmin, userDataWS.getCaName());
        if (significantcAInfo == null) {
            throw EjbcaWSHelper.getEjbcaException(
                    "Error the given CA : " + userDataWS.getCaName() + " could not be found.", logger,
                    ErrorCode.CA_NOT_EXISTS, null);
        }

        EndEntityInformation endEntityInformation = endEntityAccessSession.findUser(intAdmin,
                userDataWS.getUsername());
        if (endEntityInformation != null) {
            endEntityProfileId = endEntityInformation.getEndEntityProfileId();
            userExists = true;
        } else {
            try {
                endEntityProfileId = endEntityProfileSession
                        .getEndEntityProfileId(userDataWS.getEndEntityProfileName());
            } catch (EndEntityProfileNotFoundException e) {
                throw EjbcaWSHelper.getEjbcaException("Error given end entity profile : "
                        + userDataWS.getEndEntityProfileName() + " could not be found", logger,
                        ErrorCode.EE_PROFILE_NOT_EXISTS, null);
            }
        }

        // Approval request if we require approvals to generate token certificates
        ApprovalRequest ar = null;
        if (ejbhelper.isAdmin()) {
            final List<String> rules = new ArrayList<String>();
            rules.add(StandardRules.CREATECERT.resource());
            rules.add(AccessRulesConstants.HARDTOKEN_ISSUEHARDTOKENS);
            rules.add(StandardRules.CAACCESS.resource() + significantcAInfo.getCAId());
            if (overwriteExistingSN) {
                rules.add(AccessRulesConstants.REGULAR_REVOKEENDENTITY);
                rules.add(AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId
                        + AccessRulesConstants.REVOKE_END_ENTITY);
            }
            if (userExists) {
                rules.add(AccessRulesConstants.REGULAR_EDITENDENTITY);
                rules.add(AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId
                        + AccessRulesConstants.EDIT_END_ENTITY);
            } else {
                rules.add(AccessRulesConstants.REGULAR_CREATEENDENTITY);
                rules.add(AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId
                        + AccessRulesConstants.CREATE_END_ENTITY);
            }
            String[] rulesArray = rules.toArray(new String[rules.size()]);
            if (!authorizationSession.isAuthorizedNoLogging(admin, rulesArray)) {
                final String msg = intres.getLocalizedMessage("authorization.notuathorizedtoresource",
                        Arrays.toString(rulesArray), null);
                throw new AuthorizationDeniedException(msg);
            }
        } else {
            if (WebServiceConfiguration.getApprovalForGenTokenCertificates()) {
                ar = new GenerateTokenApprovalRequest(userDataWS.getUsername(), userDataWS.getSubjectDN(),
                        hardTokenDataWS.getLabel(), admin, null,
                        WebServiceConfiguration.getNumberOfRequiredApprovals(), significantcAInfo.getCAId(),
                        endEntityProfileId);
                int status = ApprovalDataVO.STATUS_REJECTED;
                try {
                    status = approvalSession.isApproved(admin, ar.generateApprovalId(), 1);
                    approvalSuccessfullStep1 = (status == ApprovalDataVO.STATUS_APPROVED);
                    isRejectedStep1 = (status == ApprovalDataVO.STATUS_REJECTED);
                    if (status == ApprovalDataVO.STATUS_APPROVED) {
                        ApprovalDataVO approvalDataVO = approvalSession.findNonExpiredApprovalRequest(intAdmin,
                                ar.generateApprovalId());
                        String originalDN = ((GenerateTokenApprovalRequest) approvalDataVO.getApprovalRequest())
                                .getDN();
                        userDataWS.setSubjectDN(originalDN); // replace requested DN with original DN to make sure nothing have changed.
                    } else if (status == ApprovalDataVO.STATUS_REJECTED) {
                        throw new ApprovalRequestExecutionException(
                                "The approval for id " + ar.generateApprovalId() + " has been rejected.");
                    } else if (status == ApprovalDataVO.STATUS_EXPIREDANDNOTIFIED
                            || status == ApprovalDataVO.STATUS_EXPIRED) {
                        throw new ApprovalException(
                                "The approval for id " + ar.generateApprovalId() + " has expired.");
                    } else {
                        throw new WaitingForApprovalException("The approval for id " + ar.generateApprovalId()
                                + " have not yet been approved", ar.generateApprovalId());
                    }
                } catch (ApprovalException e) {
                    approvalSession.addApprovalRequest(admin, ar);
                    throw new WaitingForApprovalException("Approval request with id " + ar.generateApprovalId()
                            + " have been added for approval.", ar.generateApprovalId());
                }
            } else {
                throw new AuthorizationDeniedException();
            }
        }

        if (ar != null && isRejectedStep1) {
            throw new ApprovalRequestExecutionException(
                    "The approval for id " + ar.generateApprovalId() + " has been rejected.");
        }

        if (ar != null && !approvalSuccessfullStep1) {
            throw new WaitingForApprovalException(
                    "The approval for id " + ar.generateApprovalId() + " has not yet been approved",
                    ar.generateApprovalId());
        }

        if (ar != null) {
            // We need to create a new AuthenticationToken here that has the "name" of the admin making the request, but that 
            // behaves like an "AlwaysAllowedAuthenticationToken". This is because the request admin does not have privileges, 
            // but we want to log as if the requesting admin performed actions below.
            final Set<? extends Principal> principals = admin.getPrincipals();
            Principal p = null;
            if (!principals.isEmpty()) {
                p = principals.iterator().next();
            } else {
                final Set<?> credentials = admin.getCredentials();
                if (!credentials.isEmpty()) {
                    final Object o = credentials.iterator().next();
                    if (o instanceof X509Certificate) {
                        final X509Certificate cert = (X509Certificate) o;
                        p = new X500Principal(cert.getSubjectDN().getName());
                    }
                } else {
                    log.error("Admin does not have neither Principals nor Credentials");
                }
            }
            admin = new AlwaysAllowLocalAuthenticationToken(p);
        }

        hardTokenExists = hardTokenSession.existsHardToken(hardTokenDataWS.getHardTokenSN());
        if (hardTokenExists) {
            if (overwriteExistingSN) {
                // fetch all old certificates and revoke them.
                Collection<java.security.cert.Certificate> currentCertificates = hardTokenSession
                        .findCertificatesInHardToken(hardTokenDataWS.getHardTokenSN());
                HardTokenInformation currentHardToken = hardTokenSession.getHardToken(admin,
                        hardTokenDataWS.getHardTokenSN(), false);
                Iterator<java.security.cert.Certificate> iter = currentCertificates.iterator();
                while (iter.hasNext()) {
                    java.security.cert.X509Certificate nextCert = (java.security.cert.X509Certificate) iter
                            .next();
                    try {
                        endEntityManagementSession.revokeCert(admin, CertTools.getSerialNumber(nextCert),
                                CertTools.getIssuerDN(nextCert), RevokedCertInfo.REVOCATION_REASON_SUPERSEDED);
                    } catch (AlreadyRevokedException e) {
                        // Ignore previously revoked certificates
                    } catch (FinderException e) {
                        throw EjbcaWSHelper.getEjbcaException(
                                "Error revoking old certificate, the user : " + currentHardToken.getUsername()
                                        + " of the old certificate couldn't be found in database.",
                                logger, ErrorCode.USER_NOT_FOUND, null);
                    }
                }

            } else {
                throw new HardTokenExistsException(
                        "Error hard token with sn " + hardTokenDataWS.getHardTokenSN() + " already exists.");
            }

        }

        if (revokePreviousCards) {
            List<HardTokenDataWS> htd = getHardTokenDatas(admin, userDataWS.getUsername(), false, true, logger);
            Iterator<HardTokenDataWS> htdIter = htd.iterator();

            while (htdIter.hasNext()) {
                HardTokenDataWS toRevoke = htdIter.next();
                try {
                    if (hardTokenDataWS.getLabel().equals(HardTokenConstants.LABEL_TEMPORARYCARD)
                            && toRevoke.getLabel() != null
                            && !toRevoke.getLabel().equals(HardTokenConstants.LABEL_TEMPORARYCARD)) {

                        // Token have extended key usage MS Logon, don't revoke it
                        Iterator<java.security.cert.Certificate> revokeCerts = hardTokenSession
                                .findCertificatesInHardToken(toRevoke.getHardTokenSN()).iterator();

                        while (revokeCerts.hasNext()) {
                            X509Certificate next = (X509Certificate) revokeCerts.next();
                            try {
                                if (WebServiceConfiguration.getSuspendAllCertificates()
                                        || next.getExtendedKeyUsage() == null || !next.getExtendedKeyUsage()
                                                .contains(KeyPurposeId.id_kp_smartcardlogon.getId())) {
                                    endEntityManagementSession.revokeCert(admin, next.getSerialNumber(),
                                            CertTools.getIssuerDN(next),
                                            RevokedCertInfo.REVOCATION_REASON_CERTIFICATEHOLD);
                                }
                            } catch (CertificateParsingException e) {
                                log.error(e);
                            } catch (FinderException e) {
                                log.error(e);
                            }
                        }

                    } else {
                        revokeToken(admin, toRevoke.getHardTokenSN(),
                                RevokedCertInfo.REVOCATION_REASON_UNSPECIFIED, logger);
                    }
                } catch (AlreadyRevokedException e) {
                    // Do nothing
                }
            }
        }

        try {
            // Check if the userdata exist and edit/add it depending on which
            String password = PasswordGeneratorFactory
                    .getInstance(PasswordGeneratorFactory.PASSWORDTYPE_ALLPRINTABLE).getNewPassword(8, 8);
            EndEntityInformation userData = ejbhelper.convertUserDataVOWS(admin, userDataWS);
            userData.setPassword(password);
            if (userExists) {
                endEntityManagementSession.changeUser(admin, userData, true);
            } else {
                endEntityManagementSession.addUser(admin, userData, true);
            }

            Date bDate = new Date(System.currentTimeMillis() - (10 * 60 * 1000));

            Iterator<TokenCertificateRequestWS> iter = tokenRequests.iterator();
            while (iter.hasNext()) {
                TokenCertificateRequestWS next = iter.next();

                int certificateProfileId = certificateProfileSession
                        .getCertificateProfileId(next.getCertificateProfileName());
                if (certificateProfileId == 0) {
                    EjbcaWSHelper
                            .getEjbcaException(
                                    "Error the given Certificate Profile : " + next.getCertificateProfileName()
                                            + " couldn't be found.",
                                    logger, ErrorCode.CERT_PROFILE_NOT_EXISTS, null);
                }

                Date eDate = null;

                if (next.getValidityIdDays() != null) {
                    try {
                        long validity = Long.parseLong(next.getValidityIdDays());
                        eDate = new Date(System.currentTimeMillis() + (validity * 3600 * 24 * 1000));
                    } catch (NumberFormatException e) {
                        EjbcaWSHelper.getEjbcaException("Error : Validity in Days must be a number", logger,
                                ErrorCode.BAD_VALIDITY_FORMAT, null);
                    }
                }

                CAInfo cAInfo = caSession.getCAInfo(admin, next.getCAName());
                if (cAInfo == null) {
                    throw EjbcaWSHelper.getEjbcaException(
                            "Error the given CA : " + next.getCAName() + " couldn't be found.", logger,
                            ErrorCode.CA_NOT_EXISTS, null);
                }

                if (!authorizationSession.isAuthorizedNoLogging(admin,
                        StandardRules.CAACCESS.resource() + cAInfo.getCAId())) {
                    final String msg = intres.getLocalizedMessage("authorization.notuathorizedtoresource",
                            StandardRules.CAACCESS.resource() + cAInfo.getCAId(), null);
                    throw new AuthorizationDeniedException(msg);
                }
                if (next.getType() == HardTokenConstants.REQUESTTYPE_PKCS10_REQUEST) {
                    userData.setCertificateProfileId(certificateProfileId);
                    userData.setCAId(cAInfo.getCAId());
                    userData.setPassword(password);
                    userData.setStatus(EndEntityConstants.STATUS_NEW);
                    endEntityManagementSession.changeUser(admin, userData, false);
                    PKCS10RequestMessage pkcs10req = new PKCS10RequestMessage(next.getPkcs10Data());
                    java.security.cert.Certificate cert;
                    if (eDate == null) {
                        cert = signSession.createCertificate(admin, userData.getUsername(), password,
                                pkcs10req.getRequestPublicKey());
                    } else {
                        cert = signSession.createCertificate(admin, userData.getUsername(), password,
                                pkcs10req.getRequestPublicKey(), -1, bDate, eDate);
                    }

                    genCertificates.add(cert);
                    retval.add(new TokenCertificateResponseWS(new Certificate(cert)));
                } else if (next.getType() == HardTokenConstants.REQUESTTYPE_KEYSTORE_REQUEST) {

                    if (!next.getTokenType().equals(HardTokenConstants.TOKENTYPE_PKCS12)) {
                        throw EjbcaWSHelper.getEjbcaException(
                                "Unsupported Key Store Type : " + next.getTokenType() + " only "
                                        + HardTokenConstants.TOKENTYPE_PKCS12 + " is supported",
                                logger, ErrorCode.NOT_SUPPORTED_KEY_STORE, null);
                    }
                    KeyPair keys = KeyTools.genKeys(next.getKeyspec(), next.getKeyalg());
                    userData.setCertificateProfileId(certificateProfileId);
                    userData.setCAId(cAInfo.getCAId());
                    userData.setPassword(password);
                    userData.setStatus(EndEntityConstants.STATUS_NEW);
                    endEntityManagementSession.changeUser(admin, userData, true);
                    X509Certificate cert;
                    if (eDate == null) {
                        cert = (X509Certificate) signSession.createCertificate(admin, userData.getUsername(),
                                password, keys.getPublic());
                    } else {
                        cert = (X509Certificate) signSession.createCertificate(admin, userData.getUsername(),
                                password, keys.getPublic(), -1, bDate, eDate);
                    }

                    genCertificates.add(cert);
                    // Generate Keystore
                    // Fetch CA Cert Chain.           
                    Collection<java.security.cert.Certificate> chain = caSession
                            .getCAInfo(admin, cAInfo.getCAId()).getCertificateChain();
                    String alias = CertTools.getPartFromDN(CertTools.getSubjectDN(cert), "CN");
                    if (alias == null) {
                        alias = userData.getUsername();
                    }
                    java.security.KeyStore pkcs12 = KeyTools.createP12(alias, keys.getPrivate(), cert, chain);

                    retval.add(new TokenCertificateResponseWS(new KeyStore(pkcs12, userDataWS.getPassword())));
                } else {
                    throw EjbcaWSHelper.getEjbcaException(
                            "Error in request, only REQUESTTYPE_PKCS10_REQUEST and REQUESTTYPE_KEYSTORE_REQUEST are supported token requests.",
                            logger, ErrorCode.NOT_SUPPORTED_REQUEST_TYPE, null);
                }
            }

        } catch (Exception e) {
            throw EjbcaWSHelper.getInternalException(e, logger);
        } finally {
            endEntityManagementSession.setUserStatus(admin, userDataWS.getUsername(),
                    EndEntityConstants.STATUS_GENERATED);
        }

        // Add hard token data
        HardToken hardToken;
        String signatureInitialPIN = "";
        String signaturePUK = "";
        String basicInitialPIN = "";
        String basicPUK = "";
        Iterator<PinDataWS> iter = hardTokenDataWS.getPinDatas().iterator();
        while (iter.hasNext()) {
            PinDataWS pinData = iter.next();
            switch (pinData.getType()) {
            case HardTokenConstants.PINTYPE_BASIC:
                basicInitialPIN = pinData.getInitialPIN();
                basicPUK = pinData.getPUK();
                break;
            case HardTokenConstants.PINTYPE_SIGNATURE:
                signatureInitialPIN = pinData.getInitialPIN();
                signaturePUK = pinData.getPUK();
                break;
            default:
                throw EjbcaWSHelper.getEjbcaException("Unsupported PIN Type " + pinData.getType(), logger,
                        ErrorCode.NOT_SUPPORTED_PIN_TYPE, null);
            }
        }
        int tokenType = SwedishEIDHardToken.THIS_TOKENTYPE;
        switch (hardTokenDataWS.getTokenType()) {
        case HardTokenConstants.TOKENTYPE_SWEDISHEID:
            hardToken = new SwedishEIDHardToken(basicInitialPIN, basicPUK, signatureInitialPIN, signaturePUK,
                    0);
            break;
        case HardTokenConstants.TOKENTYPE_ENHANCEDEID:
            hardToken = new EnhancedEIDHardToken(signatureInitialPIN, signaturePUK, basicInitialPIN, basicPUK,
                    false, 0);
            tokenType = EnhancedEIDHardToken.THIS_TOKENTYPE;
            break;
        default:
            throw EjbcaWSHelper.getEjbcaException("Unsupported Token Type : " + hardTokenDataWS.getTokenType(),
                    logger, ErrorCode.NOT_SUPPORTED_TOKEN_TYPE, null);

        }

        hardToken.setLabel(hardTokenDataWS.getLabel());
        if (overwriteExistingSN) {
            if (hardTokenExists) {
                try {
                    hardTokenSession.removeHardToken(admin, hardTokenDataWS.getHardTokenSN());
                } catch (HardTokenDoesntExistsException e) {
                    throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.HARD_TOKEN_NOT_EXISTS,
                            Level.ERROR);
                }
            }
        }
        hardTokenSession.addHardToken(admin, hardTokenDataWS.getHardTokenSN(), userDataWS.getUsername(),
                significantcAInfo.getSubjectDN(), tokenType, hardToken, genCertificates,
                hardTokenDataWS.getCopyOfSN());

        if (ar != null) {
            approvalSession.markAsStepDone(admin, ar.generateApprovalId(),
                    GenerateTokenApprovalRequest.STEP_1_GENERATETOKEN);
        }
    } catch (FinderException e) {
        throw EjbcaWSHelper.getInternalException(e, logger);
    } catch (RuntimeException e) { // EJBException, ClassCastException, ...
        throw EjbcaWSHelper.getInternalException(e, logger);
    } finally {
        logger.writeln();
        logger.flush();
    }
    return retval;
}

From source file:com.eucalyptus.www.X509Download.java

private static byte[] getX509Zip(User u) throws Exception {
    X509Certificate cloudCert = null;
    final X509Certificate x509;
    String userAccessKey = null;//from  w w  w  .j  ava2 s . c  om
    String userSecretKey = null;
    KeyPair keyPair = null;
    try {
        for (AccessKey k : u.getKeys()) {
            if (k.isActive()) {
                userAccessKey = k.getAccessKey();
                userSecretKey = k.getSecretKey();
            }
        }
        if (userAccessKey == null) {
            AccessKey k = u.createKey();
            userAccessKey = k.getAccessKey();
            userSecretKey = k.getSecretKey();
        }
        keyPair = Certs.generateKeyPair();
        x509 = Certs.generateCertificate(keyPair, u.getName());
        x509.checkValidity();
        u.addCertificate(x509);
        cloudCert = SystemCredentials.lookup(Eucalyptus.class).getCertificate();
    } catch (Exception e) {
        LOG.fatal(e, e);
        throw e;
    }
    ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
    ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(byteOut);
    ZipArchiveEntry entry = null;
    String fingerPrint = Certs.getFingerPrint(keyPair.getPublic());
    if (fingerPrint != null) {
        String baseName = X509Download.NAME_SHORT + "-" + u.getName() + "-"
                + fingerPrint.replaceAll(":", "").toLowerCase().substring(0, 8);

        zipOut.setComment("To setup the environment run: source /path/to/eucarc");
        StringBuilder sb = new StringBuilder();
        //TODO:GRZE:FIXME velocity
        String userNumber = u.getAccount().getAccountNumber();
        sb.append("EUCA_KEY_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd -P)");
        final Optional<String> computeUrl = remotePublicify(Compute.class);
        if (computeUrl.isPresent()) {
            sb.append(entryFor("EC2_URL", null, computeUrl));
        } else {
            sb.append("\necho WARN:  Eucalyptus URL is not configured. >&2");
            ServiceBuilder<? extends ServiceConfiguration> builder = ServiceBuilders.lookup(Compute.class);
            ServiceConfiguration localConfig = builder.newInstance(Internets.localHostAddress(),
                    Internets.localHostAddress(), Internets.localHostAddress(), Eucalyptus.INSTANCE.getPort());
            sb.append("\nexport EC2_URL=" + ServiceUris.remotePublicify(localConfig));
        }

        sb.append(entryFor("S3_URL", "An OSG is either not registered or not configured. S3_URL is not set. "
                + "Please register an OSG and/or set a valid s3 endpoint and download credentials again. "
                + "Or set S3_URL manually to http://OSG-IP:8773/services/objectstorage",
                remotePublicify(ObjectStorage.class)));
        sb.append(entryFor("EUARE_URL", "EUARE URL is not configured.", remotePublicify(Euare.class)));
        sb.append(entryFor("TOKEN_URL", "TOKEN URL is not configured.", remotePublicify(Tokens.class)));
        sb.append(entryFor("AWS_AUTO_SCALING_URL", "Auto Scaling service URL is not configured.",
                remotePublicify(AutoScaling.class)));
        sb.append(entryFor("AWS_CLOUDFORMATION_URL", null, remotePublicify(CloudFormation.class)));
        sb.append(entryFor("AWS_CLOUDWATCH_URL", "Cloud Watch service URL is not configured.",
                remotePublicify(CloudWatch.class)));
        sb.append(entryFor("AWS_ELB_URL", "Load Balancing service URL is not configured.",
                remotePublicify(LoadBalancing.class)));
        sb.append("\nexport EUSTORE_URL=" + StackConfiguration.DEFAULT_EUSTORE_URL);
        sb.append("\nexport EC2_PRIVATE_KEY=${EUCA_KEY_DIR}/" + baseName + "-pk.pem");
        sb.append("\nexport EC2_CERT=${EUCA_KEY_DIR}/" + baseName + "-cert.pem");
        sb.append("\nexport EC2_JVM_ARGS=-Djavax.net.ssl.trustStore=${EUCA_KEY_DIR}/jssecacerts");
        sb.append("\nexport EUCALYPTUS_CERT=${EUCA_KEY_DIR}/cloud-cert.pem");
        sb.append("\nexport EC2_ACCOUNT_NUMBER='" + u.getAccount().getAccountNumber() + "'");
        sb.append("\nexport EC2_ACCESS_KEY='" + userAccessKey + "'");
        sb.append("\nexport EC2_SECRET_KEY='" + userSecretKey + "'");
        sb.append("\nexport AWS_ACCESS_KEY='" + userAccessKey + "'");
        sb.append("\nexport AWS_SECRET_KEY='" + userSecretKey + "'");
        sb.append("\nexport AWS_CREDENTIAL_FILE=${EUCA_KEY_DIR}/iamrc");
        sb.append("\nexport EC2_USER_ID='" + userNumber + "'");
        sb.append(
                "\nalias ec2-bundle-image=\"ec2-bundle-image --cert ${EC2_CERT} --privatekey ${EC2_PRIVATE_KEY} --user ${EC2_ACCOUNT_NUMBER} --ec2cert ${EUCALYPTUS_CERT}\"");
        sb.append(
                "\nalias ec2-upload-bundle=\"ec2-upload-bundle -a ${EC2_ACCESS_KEY} -s ${EC2_SECRET_KEY} --url ${S3_URL}\"");
        sb.append("\n");
        zipOut.putArchiveEntry(entry = new ZipArchiveEntry("eucarc"));
        entry.setUnixMode(0600);
        zipOut.write(sb.toString().getBytes("UTF-8"));
        zipOut.closeArchiveEntry();

        sb = new StringBuilder();
        sb.append("AWSAccessKeyId=").append(userAccessKey).append('\n');
        sb.append("AWSSecretKey=").append(userSecretKey);
        zipOut.putArchiveEntry(entry = new ZipArchiveEntry("iamrc"));
        entry.setUnixMode(0600);
        zipOut.write(sb.toString().getBytes("UTF-8"));
        zipOut.closeArchiveEntry();

        /** write the private key to the zip stream **/
        zipOut.putArchiveEntry(entry = new ZipArchiveEntry("cloud-cert.pem"));
        entry.setUnixMode(0600);
        zipOut.write(PEMFiles.getBytes(cloudCert));
        zipOut.closeArchiveEntry();

        zipOut.putArchiveEntry(entry = new ZipArchiveEntry("jssecacerts"));
        entry.setUnixMode(0600);
        KeyStore tempKs = KeyStore.getInstance("jks");
        tempKs.load(null);
        tempKs.setCertificateEntry("eucalyptus", cloudCert);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        tempKs.store(bos, "changeit".toCharArray());
        zipOut.write(bos.toByteArray());
        zipOut.closeArchiveEntry();

        /** write the private key to the zip stream **/
        zipOut.putArchiveEntry(entry = new ZipArchiveEntry(baseName + "-pk.pem"));
        entry.setUnixMode(0600);
        zipOut.write(PEMFiles.getBytes("RSA PRIVATE KEY",
                Crypto.getCertificateProvider().getEncoded(keyPair.getPrivate())));
        zipOut.closeArchiveEntry();

        /** write the X509 certificate to the zip stream **/
        zipOut.putArchiveEntry(entry = new ZipArchiveEntry(baseName + "-cert.pem"));
        entry.setUnixMode(0600);
        zipOut.write(PEMFiles.getBytes(x509));
        zipOut.closeArchiveEntry();
    }
    /** close the zip output stream and return the bytes **/
    zipOut.close();
    return byteOut.toByteArray();
}

From source file:org.ejbca.core.model.ca.caadmin.CVCCA.java

/** If the request is a CVC request, this method adds an outer signature to the request.
 * If this request is a CVCA certificate and this is the same CVCA, this method creates a CVCA link certificate.
 * If not creating a link certificate this means that an authenticated request, CVCAuthenticatedRequest is created.
 * /*from  w  ww. ja v a2  s. c om*/
 * @see CA#signRequest(byte[], boolean, boolean)
 */
public byte[] signRequest(byte[] request, boolean usepreviouskey, boolean createlinkcert)
        throws CATokenOfflineException {
    if (log.isTraceEnabled()) {
        log.trace(">signRequest: usepreviouskey=" + usepreviouskey + ", createlinkcert=" + createlinkcert);
    }
    byte[] ret = request;
    try {
        CardVerifiableCertificate cacert = (CardVerifiableCertificate) getCACertificate();
        if (cacert == null) {
            // if we don't have a CA certificate, we can't sign any request, just return it
            return request;
        }
        CATokenContainer catoken = getCAToken();
        // Get either the current or the previous signing key for signing this request
        int key = SecConst.CAKEYPURPOSE_CERTSIGN;
        if (usepreviouskey) {
            log.debug("Using previous CertSign key to sign request");
            key = SecConst.CAKEYPURPOSE_CERTSIGN_PREVIOUS;
        } else {
            log.debug("Using current CertSign key to sign request");
        }
        KeyPair keyPair = new KeyPair(catoken.getPublicKey(key), catoken.getPrivateKey(key));
        String signAlg = getCAToken().getCATokenInfo().getSignatureAlgorithm();
        // Create the CA reference, should be from signing certificates holder field
        HolderReferenceField caHolder = cacert.getCVCertificate().getCertificateBody().getHolderReference();
        String sequence = caHolder.getSequence();
        // See if we have a previous sequence to put in the CA reference instead of the same as we have from the request
        String propdata = catoken.getCATokenInfo().getProperties();
        Properties prop = new Properties();
        if (propdata != null) {
            prop.load(new ByteArrayInputStream(propdata.getBytes()));
        }
        String previousSequence = (String) prop.get(ICAToken.PREVIOUS_SEQUENCE_PROPERTY);
        // Only use previous sequence if we also use previous key
        if ((previousSequence != null) && (usepreviouskey)) {
            sequence = previousSequence;
            log.debug("Using previous sequence in caRef: " + sequence);
        } else {
            log.debug("Using current sequence in caRef: " + sequence);
        }
        // Set the CA reference field for the authentication signature
        CAReferenceField caRef = new CAReferenceField(caHolder.getCountry(), caHolder.getMnemonic(), sequence);

        CVCertificate cvcert = null;
        try {
            byte[] binbytes = request;
            try {
                // We don't know if this is a PEM or binary certificate or request request so we first try to 
                // decode it as a PEM certificate, and if it's not we try it as a PEM request and finally as a binary request 
                Collection<Certificate> col = CertTools.getCertsFromPEM(new ByteArrayInputStream(request));
                Certificate cert = col.iterator().next();
                if (cert != null) {
                    binbytes = cert.getEncoded();
                }
            } catch (Exception e) {
                log.debug("This is not a PEM certificate?: " + e.getMessage());
                try {
                    binbytes = RequestMessageUtils.getRequestBytes(request);
                } catch (Exception e2) {
                    log.debug("This is not a PEM request?: " + e2.getMessage());
                }
            }
            // This can be either a CV certificate, a CV certificate request, or an authenticated request that we should re-sign
            CVCObject parsedObject;
            parsedObject = CertificateParser.parseCVCObject(binbytes);
            if (parsedObject instanceof CVCertificate) {
                cvcert = (CVCertificate) parsedObject;
                log.debug("This is a reqular CV request, or cert.");
            } else if (parsedObject instanceof CVCAuthenticatedRequest) {
                CVCAuthenticatedRequest authreq = (CVCAuthenticatedRequest) parsedObject;
                cvcert = authreq.getRequest();
                log.debug(
                        "This is an authenticated CV request, we will overwrite the old authentication with a new.");
            }
        } catch (ParseException e) {
            String msg = intres.getLocalizedMessage("cvc.error.notcvcrequest");
            log.info(msg, e);
            return request;
        } catch (ClassCastException e) {
            String msg = intres.getLocalizedMessage("cvc.error.notcvcrequest");
            log.info(msg, e);
            return request;
        }
        // Check if the input was a CVCA certificate, which is the same CVCA as this. If all is true we should create a CVCA link certificate
        // instead of an authenticated request
        CardVerifiableCertificate cvccert = new CardVerifiableCertificate(cvcert);
        HolderReferenceField cvccertholder = cvccert.getCVCertificate().getCertificateBody()
                .getHolderReference();
        AuthorizationRoleEnum authRole = null;
        AccessRightEnum rights = null;
        try {
            authRole = cvccert.getCVCertificate().getCertificateBody().getAuthorizationTemplate()
                    .getAuthorizationField().getRole();
            rights = cvccert.getCVCertificate().getCertificateBody().getAuthorizationTemplate()
                    .getAuthorizationField().getAccessRight();
        } catch (NoSuchFieldException e) {
            log.debug(
                    "No AuthorizationRoleEnum or AccessRightEnum, this is not a CV certificate so we can't make a link certificate: "
                            + e.getMessage());

        }
        if (createlinkcert && (authRole != null) && (rights != null)) {
            log.debug("We will create a link certificate.");
            String msg = intres.getLocalizedMessage("cvc.info.createlinkcert", cvccertholder.getConcatenated(),
                    caRef.getConcatenated());
            log.info(msg);
            PublicKey pk = cvccert.getPublicKey();
            Date validFrom = cvccert.getCVCertificate().getCertificateBody().getValidFrom();
            Date validTo = cvccert.getCVCertificate().getCertificateBody().getValidTo();
            // Generate a new certificate with the same contents as the passed in certificate, but with new caRef and signature
            CVCertificate retcert = CertificateGenerator.createCertificate(pk, keyPair.getPrivate(), signAlg,
                    caRef, cvccertholder, authRole, rights, validFrom, validTo, catoken.getProvider());
            ret = retcert.getDEREncoded();
            log.debug("Signed a CardVerifiableCertificate CardVerifiableCertificate.");
        } else {
            log.debug("Creating authenticated request with signature alg: " + signAlg + ", using provider "
                    + catoken.getProvider());
            CVCAuthenticatedRequest authreq = CertificateGenerator.createAuthenticatedRequest(cvcert, keyPair,
                    signAlg, caRef, catoken.getProvider());
            ret = authreq.getDEREncoded();
            log.debug("Signed a CardVerifiableCertificate request and returned a CVCAuthenticatedRequest.");
        }
    } catch (IllegalKeyStoreException e) {
        throw new RuntimeException(e);
    } catch (InvalidKeyException e) {
        throw new RuntimeException(e);
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    } catch (NoSuchProviderException e) {
        throw new RuntimeException(e);
    } catch (SignatureException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (ConstructionException e) {
        throw new RuntimeException(e);
    } catch (NoSuchFieldException e) {
        throw new RuntimeException(e);
    }
    if (log.isTraceEnabled()) {
        log.trace("<signRequest");
    }
    return ret;
}

From source file:com.trsst.client.Client.java

/**
 * Posts a new entry to the feed associated with the specified public
 * signing key to the home server, creating a new feed if needed.
 * //from w w  w. j a  va2  s  .co  m
 * @param signingKeys
 *            Required: the signing keys associated with public feed id of
 *            this feed.
 * @param encryptionKey
 *            Required: the public encryption key associated with this
 *            account; this public key will be used by others to encrypt
 *            private message for this account.
 * @param options
 *            The data to be posted.
 * @return The feed as posted to the home server.
 * @throws IOException
 * @throws SecurityException
 * @throws GeneralSecurityException
 * @throws contentKey
 */
public Feed post(KeyPair signingKeys, KeyPair encryptionKeys, EntryOptions options, FeedOptions feedOptions)
        throws IOException, SecurityException, GeneralSecurityException, Exception {
    // inlining all the steps to help implementors and porters (and
    // debuggers)

    // configure for signing
    Element signedNode, signatureElement, keyInfo;
    AbderaSecurity security = new AbderaSecurity(Abdera.getInstance());
    Signature signer = security.getSignature();

    String feedId = Common.toFeedId(signingKeys.getPublic());
    Feed feed = pull(feedId);
    if (feed == null) {
        feed = Abdera.getInstance().newFeed();
        feed.declareNS(Common.NS_URI, Common.NS_ABBR);
    }

    // remove each entry and retain the most recent one (if any)
    List<Entry> entries = feed.getEntries();
    Entry mostRecentEntry = null;
    for (Entry entry : entries) {
        if (mostRecentEntry == null || mostRecentEntry.getUpdated() == null
                || mostRecentEntry.getUpdated().before(entry.getUpdated())) {
            mostRecentEntry = entry;
        }
        entry.discard();
    }

    // update and sign feed (without any entries)
    feed.setUpdated(new Date());

    // ensure the correct keys are in place
    signatureElement = feed.getFirstChild(new QName(Common.NS_URI, Common.SIGN));
    if (signatureElement != null) {
        signatureElement.discard();
    }
    feed.addExtension(new QName(Common.NS_URI, Common.SIGN))
            .setText(Common.toX509FromPublicKey(signingKeys.getPublic()));
    signatureElement = feed.getFirstChild(new QName(Common.NS_URI, Common.ENCRYPT));
    if (signatureElement != null) {
        signatureElement.discard();
    }
    feed.addExtension(new QName(Common.NS_URI, Common.ENCRYPT))
            .setText(Common.toX509FromPublicKey(encryptionKeys.getPublic()));
    feed.setId(Common.toFeedUrn(feedId));
    feed.setMustPreserveWhitespace(false);

    // update feed properties
    if (feedOptions.title != null) {
        feed.setTitle(feedOptions.title);
    }
    if (feedOptions.subtitle != null) {
        feed.setSubtitle(feedOptions.subtitle);
    }
    if (feedOptions.icon != null) {
        while (feed.getIconElement() != null) {
            feed.getIconElement().discard();
        }
        feed.setIcon(feedOptions.icon);
    }
    if (feedOptions.logo != null) {
        while (feed.getLogoElement() != null) {
            feed.getLogoElement().discard();
        }
        feed.setLogo(feedOptions.logo);
    }

    Person author = feed.getAuthor();
    if (author == null) {
        // author is a required element
        author = Abdera.getInstance().getFactory().newAuthor();
        String defaultName = feed.getTitle();
        if (defaultName == null) {
            defaultName = Common.toFeedIdString(feed.getId());
        }
        author.setName(defaultName);
        feed.addAuthor(author);
    }

    // update author
    if (feedOptions.name != null || feedOptions.email != null || feedOptions.uri != null) {
        if (feedOptions.name != null) {
            author.setName(feedOptions.name);
        }
        if (feedOptions.email != null) {
            author.setEmail(feedOptions.email);
        }
        if (feedOptions.uri != null) {
            if (feedOptions.uri.indexOf(':') == -1) {
                // default to "acct:" urn
                author.setUri("acct:" + feedOptions.uri + ".trsst.com");
                // FIXME: domain should be specified by user
            } else {
                author.setUri(feedOptions.uri);
            }
        }
    }

    // set base
    if (feedOptions.base != null) {
        String uri = feedOptions.base;
        if (!uri.endsWith("/")) {
            uri = uri + '/';
        }
        uri = uri + feedId;
        feed.setBaseUri(uri);
    }

    // set link self
    IRI base = feed.getBaseUri();
    if (base != null) {
        while (feed.getLink(Link.REL_SELF) != null) {
            feed.getLink(Link.REL_SELF).discard();
        }
        feed.addLink(base.toString(), Link.REL_SELF);
    }

    // holds any attachments (can be used for logo and icons)
    String[] contentIds = new String[options.getContentCount()];

    // subject or verb or attachment is required to create an entry
    Entry entry = null;
    if (options.status != null || options.verb != null || contentIds.length > 0) {

        // create the new entry
        entry = Abdera.getInstance().newEntry();
        entry.setUpdated(feed.getUpdated());
        entry.setId(Common.toEntryUrn(feedId, feed.getUpdated().getTime()));
        entry.addLink(feedId + '/' + Common.toEntryIdString(entry.getId()));
        if (options.publish != null) {
            entry.setPublished(options.publish);
        } else {
            entry.setPublished(entry.getUpdated());
        }

        if (options.status != null) {
            entry.setTitle(options.status);
        } else {
            // title is a required element:
            // default to verb
            if (options.verb != null) {
                entry.setTitle(options.verb);
            } else {
                // "post" is the default verb
                entry.setSummary("post");
            }
        }

        if (options.verb != null) {
            feed.declareNS("http://activitystrea.ms/spec/1.0/", "activity");
            entry.addSimpleExtension(new QName("http://activitystrea.ms/spec/1.0/", "verb", "activity"),
                    options.verb);
        }

        if (options.body != null) {
            // was: entry.setSummary(options.body);
            entry.setSummary(options.body, org.apache.abdera.model.Text.Type.HTML);
            // FIXME: some readers only show type=html
        } else {
            // summary is a required element in some cases
            entry.setSummary("", org.apache.abdera.model.Text.Type.TEXT);
            // FIXME: use tika to generate a summary
        }

        // generate proof-of-work stamp for this feed id and entry id
        Element stampElement = entry.addExtension(new QName(Common.NS_URI, Common.STAMP));
        stampElement.setText(Crypto.computeStamp(Common.STAMP_BITS, entry.getUpdated().getTime(), feedId));

        if (options.mentions != null) {
            HashSet<String> set = new HashSet<String>();
            for (String s : options.mentions) {
                if (!set.contains(s)) {
                    set.add(s); // prevent duplicates
                    entry.addCategory(Common.MENTION_URN, s, "Mention");
                    stampElement = entry.addExtension(new QName(Common.NS_URI, Common.STAMP));
                    stampElement
                            .setText(Crypto.computeStamp(Common.STAMP_BITS, entry.getUpdated().getTime(), s));
                    // stamp is required for each mention
                }
            }
        }
        if (options.tags != null) {
            HashSet<String> set = new HashSet<String>();
            for (String s : options.tags) {
                if (!set.contains(s)) {
                    set.add(s); // prevent duplicates
                    entry.addCategory(Common.TAG_URN, s, "Tag");
                    stampElement = entry.addExtension(new QName(Common.NS_URI, Common.STAMP));
                    stampElement
                            .setText(Crypto.computeStamp(Common.STAMP_BITS, entry.getUpdated().getTime(), s));
                    // stamp is required for each tag
                }
            }
        }

        // generate an AES256 key for encrypting
        byte[] contentKey = null;
        if (options.recipientIds != null) {
            contentKey = Crypto.generateAESKey();
        }

        // for each content part
        for (int part = 0; part < contentIds.length; part++) {
            byte[] currentContent = options.getContentData()[part];
            String currentType = options.getMimetypes()[part];

            // encrypt before hashing if necessary
            if (contentKey != null) {
                currentContent = Crypto.encryptAES(currentContent, contentKey);
            }

            // calculate digest to determine content id
            byte[] digest = Common.ripemd160(currentContent);
            contentIds[part] = new Base64(0, null, true).encodeToString(digest);

            // add mime-type hint to content id (if not encrypted):
            // (some readers like to see a file extension on enclosures)
            if (currentType != null && contentKey == null) {
                String extension = "";
                int i = currentType.lastIndexOf('/');
                if (i != -1) {
                    extension = '.' + currentType.substring(i + 1);
                }
                contentIds[part] = contentIds[part] + extension;
            }

            // set the content element
            if (entry.getContentSrc() == null) {
                // only point to the first attachment if multiple
                entry.setContent(new IRI(contentIds[part]), currentType);
            }

            // use a base uri so src attribute is simpler to process
            entry.getContentElement().setBaseUri(Common.toEntryIdString(entry.getId()) + '/');
            entry.getContentElement().setAttributeValue(new QName(Common.NS_URI, "hash", "trsst"), "ripemd160");

            // if not encrypted
            if (contentKey == null) {
                // add an enclosure link
                entry.addLink(Common.toEntryIdString(entry.getId()) + '/' + contentIds[part],
                        Link.REL_ENCLOSURE, currentType, null, null, currentContent.length);
            }

        }

        if (contentIds.length == 0 && options.url != null) {
            Content content = Abdera.getInstance().getFactory().newContent();
            if (options.url.startsWith("urn:feed:") || options.url.startsWith("urn:entry:")) {
                content.setMimeType("application/atom+xml");
            } else {
                content.setMimeType("text/html");
            }
            content.setSrc(options.url);
            entry.setContentElement(content);
        }

        // add the previous entry's signature value
        String predecessor = null;
        if (mostRecentEntry != null) {
            signatureElement = mostRecentEntry
                    .getFirstChild(new QName("http://www.w3.org/2000/09/xmldsig#", "Signature"));
            if (signatureElement != null) {
                signatureElement = signatureElement
                        .getFirstChild(new QName("http://www.w3.org/2000/09/xmldsig#", "SignatureValue"));
                if (signatureElement != null) {
                    predecessor = signatureElement.getText();
                    signatureElement = entry.addExtension(new QName(Common.NS_URI, Common.PREDECESSOR));
                    signatureElement.setText(predecessor);
                    signatureElement.setAttributeValue(Common.PREDECESSOR_ID,
                            mostRecentEntry.getId().toString());
                } else {
                    log.error("No signature value found for entry: " + entry.getId());
                }
            } else {
                log.error("No signature found for entry: " + entry.getId());
            }
        }

        if (options.recipientIds == null) {
            // public post
            entry.setRights(Common.RIGHTS_NDBY_REVOCABLE);
        } else {
            // private post
            entry.setRights(Common.RIGHTS_RESERVED);
            try {
                StringWriter stringWriter = new StringWriter();
                StreamWriter writer = Abdera.getInstance().getWriterFactory().newStreamWriter();
                writer.setWriter(stringWriter);
                writer.startEntry();
                writer.writeId(entry.getId());
                writer.writeUpdated(entry.getUpdated());
                writer.writePublished(entry.getPublished());
                if (predecessor != null) {
                    writer.startElement(Common.PREDECESSOR, Common.NS_URI);
                    writer.writeElementText(predecessor);
                    writer.endElement();
                }
                if (options.publicOptions != null) {
                    // these are options that will be publicly visible
                    if (options.publicOptions.status != null) {
                        writer.writeTitle(options.publicOptions.status);
                    } else {
                        writer.writeTitle(""); // empty title
                    }
                    if (options.publicOptions.body != null) {
                        writer.writeSummary(options.publicOptions.body);
                    }
                    if (options.publicOptions.verb != null) {
                        writer.startElement("verb", "http://activitystrea.ms/spec/1.0/");
                        writer.writeElementText(options.publicOptions.verb);
                        writer.endElement();
                    }
                    if (options.publicOptions.tags != null) {
                        for (String s : options.publicOptions.tags) {
                            writer.writeCategory(s);
                        }
                    }
                    if (options.publicOptions.mentions != null) {
                        for (String s : options.publicOptions.mentions) {
                            writer.startElement("mention", Common.NS_URI, "trsst");
                            writer.writeElementText(s);
                            writer.endElement();
                        }
                    }
                } else {
                    writer.writeTitle(""); // empty title
                }

                writer.startContent("application/xenc+xml");

                List<PublicKey> keys = new LinkedList<PublicKey>();
                for (String id : options.recipientIds) {
                    // for each recipient
                    Feed recipientFeed = pull(id);
                    if (recipientFeed != null) {
                        // fetch encryption key
                        Element e = recipientFeed.getExtension(new QName(Common.NS_URI, Common.ENCRYPT));
                        if (e == null) {
                            // fall back to signing key
                            e = recipientFeed.getExtension(new QName(Common.NS_URI, Common.SIGN));
                        }
                        keys.add(Common.toPublicKeyFromX509(e.getText()));
                    }
                }

                // enforce the convention:
                keys.remove(encryptionKeys.getPublic());
                // move to end if exists;
                // last encrypted key is for ourself
                keys.add(encryptionKeys.getPublic());

                // encrypt content key separately for each recipient
                for (PublicKey recipient : keys) {
                    byte[] bytes = Crypto.encryptKeyWithIES(contentKey, feed.getUpdated().getTime(), recipient,
                            encryptionKeys.getPrivate());
                    String encoded = new Base64(0, null, true).encodeToString(bytes);
                    writer.startElement("EncryptedData", "http://www.w3.org/2001/04/xmlenc#");
                    writer.startElement("CipherData", "http://www.w3.org/2001/04/xmlenc#");
                    writer.startElement("CipherValue", "http://www.w3.org/2001/04/xmlenc#");
                    writer.writeElementText(encoded);
                    writer.endElement();
                    writer.endElement();
                    writer.endElement();
                }

                // now: encrypt the payload with content key
                byte[] bytes = encryptElementAES(entry, contentKey);
                String encoded = new Base64(0, null, true).encodeToString(bytes);
                writer.startElement("EncryptedData", "http://www.w3.org/2001/04/xmlenc#");
                writer.startElement("CipherData", "http://www.w3.org/2001/04/xmlenc#");
                writer.startElement("CipherValue", "http://www.w3.org/2001/04/xmlenc#");
                writer.writeElementText(encoded);
                writer.endElement();
                writer.endElement();
                writer.endElement();

                // done with encrypted elements
                writer.endContent();
                writer.endEntry();
                writer.flush();
                // this constructed entry now replaces the encrypted
                // entry
                entry = (Entry) Abdera.getInstance().getParserFactory().getParser()
                        .parse(new StringReader(stringWriter.toString())).getRoot();
                // System.out.println(stringWriter.toString());
            } catch (Throwable t) {
                log.error("Unexpected error while encrypting, exiting: " + options.recipientIds, t);
                t.printStackTrace();
                throw new IllegalArgumentException("Unexpected error: " + t);
            }
        }

        // sign the new entry
        signedNode = signer.sign(entry, getSignatureOptions(signer, signingKeys));
        signatureElement = signedNode
                .getFirstChild(new QName("http://www.w3.org/2000/09/xmldsig#", "Signature"));
        keyInfo = signatureElement.getFirstChild(new QName("http://www.w3.org/2000/09/xmldsig#", "KeyInfo"));
        if (keyInfo != null) {
            // remove key info (because we're not using certs)
            keyInfo.discard();
        }
        entry.addExtension(signatureElement);
    } else {
        log.info("No valid entries detected; updating feed.");
    }

    // remove existing feed signature element if any
    signatureElement = feed.getFirstChild(new QName("http://www.w3.org/2000/09/xmldsig#", "Signature"));
    if (signatureElement != null) {
        signatureElement.discard();
    }

    // remove all navigation links before signing
    for (Link link : feed.getLinks()) {
        if (Link.REL_FIRST.equals(link.getRel()) || Link.REL_LAST.equals(link.getRel())
                || Link.REL_CURRENT.equals(link.getRel()) || Link.REL_NEXT.equals(link.getRel())
                || Link.REL_PREVIOUS.equals(link.getRel())) {
            link.discard();
        }
    }

    // remove all opensearch elements before signing
    for (Element e : feed.getExtensions("http://a9.com/-/spec/opensearch/1.1/")) {
        e.discard();
    }

    // set logo and/or icon
    if (contentIds.length > 0) {
        String url = Common.toEntryIdString(entry.getId()) + '/' + contentIds[0];
        if (feedOptions.asIcon) {
            feed.setIcon(url);
        }
        if (feedOptions.asLogo) {
            feed.setLogo(url);
        }
    }

    // sign the feed
    signedNode = signer.sign(feed, getSignatureOptions(signer, signingKeys));
    signatureElement = signedNode.getFirstChild(new QName("http://www.w3.org/2000/09/xmldsig#", "Signature"));
    keyInfo = signatureElement.getFirstChild(new QName("http://www.w3.org/2000/09/xmldsig#", "KeyInfo"));
    if (keyInfo != null) {
        // remove key info (because we're not using certs)
        keyInfo.discard();
    }
    feed.addExtension(signatureElement);

    // add the new entry to the feed, if there is one,
    // only after we have signed the feed
    if (entry != null) {
        feed.addEntry(entry);
    }

    // post to server
    if (contentIds.length > 0) {
        return push(feed, contentIds, options.getMimetypes(), options.getContentData(), serving);
    }
    return push(feed, serving);
}