Example usage for org.bouncycastle.jce PKCS10CertificationRequest getPublicKey

List of usage examples for org.bouncycastle.jce PKCS10CertificationRequest getPublicKey

Introduction

In this page you can find the example usage for org.bouncycastle.jce PKCS10CertificationRequest getPublicKey.

Prototype

public PublicKey getPublicKey() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException 

Source Link

Document

return the public key associated with the certification request - the public key is created using the BC provider.

Usage

From source file:ca.nrc.cadc.cred.CertUtil.java

License:Open Source License

/**
 * Method that generates an X509 proxy certificate
 * /*from   www  .  ja  v  a  2s  .  c  om*/
 * @param csr CSR for the certificate
 * @param lifetime lifetime of the certificate in SECONDS
 * @param chain certificate used to sign the proxy certificate
 * @return generated proxy certificate
 * @throws NoSuchAlgorithmException
 * @throws NoSuchProviderException
 * @throws InvalidKeyException
 * @throws CertificateParsingException
 * @throws CertificateEncodingException
 * @throws SignatureException
 * @throws CertificateNotYetValidException
 * @throws CertificateExpiredException
 */
public static X509Certificate generateCertificate(PKCS10CertificationRequest csr, int lifetime,
        X509CertificateChain chain) throws NoSuchAlgorithmException, NoSuchProviderException,
        InvalidKeyException, CertificateParsingException, CertificateEncodingException, SignatureException,
        CertificateExpiredException, CertificateNotYetValidException {
    X509Certificate issuerCert = chain.getChain()[0];
    PrivateKey issuerKey = chain.getPrivateKey();

    Security.addProvider(new BouncyCastleProvider());

    X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();

    certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
    certGen.setIssuerDN(issuerCert.getSubjectX500Principal());

    // generate the proxy DN as the issuerDN + CN=random number
    Random rand = new Random();
    String issuerDN = issuerCert.getSubjectX500Principal().getName(X500Principal.RFC2253);
    String delegDN = String.valueOf(Math.abs(rand.nextInt()));
    String proxyDn = "CN=" + delegDN + "," + issuerDN;
    certGen.setSubjectDN(new X500Principal(proxyDn));

    // set validity
    GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    // Start date. Allow for a sixty five minute clock skew here.
    date.add(Calendar.MINUTE, -65);
    Date beforeDate = date.getTime();
    for (X509Certificate currentCert : chain.getChain()) {
        if (beforeDate.before(currentCert.getNotBefore())) {
            beforeDate = currentCert.getNotBefore();
        }
    }
    certGen.setNotBefore(beforeDate);

    // End date.
    // If hours = 0, then cert lifetime is set to that of user cert
    if (lifetime <= 0) {
        // set the validity of certificates as the minimum
        // of the certificates in the chain
        Date afterDate = issuerCert.getNotAfter();
        for (X509Certificate currentCert : chain.getChain()) {
            if (afterDate.after(currentCert.getNotAfter())) {
                afterDate = currentCert.getNotAfter();
            }
        }
        certGen.setNotAfter(afterDate);
    } else {
        // check the validity of the signing certificate
        date.add(Calendar.MINUTE, 5);
        date.add(Calendar.SECOND, lifetime);
        for (X509Certificate currentCert : chain.getChain()) {
            currentCert.checkValidity(date.getTime());
        }

        certGen.setNotAfter(date.getTime());
    }

    certGen.setPublicKey(csr.getPublicKey());
    // TODO: should be able to get signature algorithm from the csr, but... obtuse
    certGen.setSignatureAlgorithm(DEFAULT_SIGNATURE_ALGORITHM);

    // extensions
    // add ProxyCertInfo extension to the new cert

    certGen.addExtension(X509Extensions.KeyUsage, true,
            new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment));

    certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
            new AuthorityKeyIdentifierStructure(issuerCert));

    certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
            new SubjectKeyIdentifierStructure(csr.getPublicKey("BC")));

    certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false));

    // add the Proxy Certificate Information
    // I expect this code to be removed once support to proxy
    // certificates is provided in Bouncy Castle.

    // create a proxy policy
    // types of proxy certificate policies - see RFC3820
    // impersonates the user
    final DERObjectIdentifier IMPERSONATION = new DERObjectIdentifier("1.3.6.1.5.5.7.21.1");
    // independent
    // final DERObjectIdentifier INDEPENDENT = new
    // DERObjectIdentifier(
    // "1.3.6.1.5.5.7.21.2");
    // defined by a policy language
    // final DERObjectIdentifier LIMITED = new DERObjectIdentifier(
    // "1.3.6.1.4.1.3536.1.1.1.9");

    ASN1EncodableVector policy = new ASN1EncodableVector();
    policy.add(IMPERSONATION);

    // pathLengthConstr (RFC3820)
    // The pCPathLenConstraint field, if present, specifies the
    // maximum
    // depth of the path of Proxy Certificates that can be signed by
    // this
    // Proxy Certificate. A pCPathLenConstraint of 0 means that this
    // certificate MUST NOT be used to sign a Proxy Certificate. If
    // the
    // pCPathLenConstraint field is not present then the maximum proxy
    // path
    // length is unlimited. End entity certificates have unlimited
    // maximum
    // proxy path lengths.
    // DERInteger pathLengthConstr = new DERInteger(100);

    // create the proxy certificate information
    ASN1EncodableVector vec = new ASN1EncodableVector();
    // policy.add(pathLengthConstr);
    vec.add(new DERSequence(policy));

    // OID
    final DERObjectIdentifier OID = new DERObjectIdentifier("1.3.6.1.5.5.7.1.14");
    certGen.addExtension(OID, true, new DERSequence(vec));

    return certGen.generate(issuerKey, "BC");
}

From source file:com.igeekinc.indelible.indeliblefs.security.EntityAuthenticationServerCore.java

License:Open Source License

public EntityAuthentication authenticateServer(EntityID serverID, byte[] encodedCertReq)
        throws CertificateEncodingException, InvalidKeyException, IllegalStateException,
        NoSuchProviderException, NoSuchAlgorithmException, SignatureException, UnrecoverableKeyException,
        KeyStoreException, IOException, CertificateParsingException, ServerNotRegisteredException,
        AuthenticationFailureException {
    Date startDate = new Date(System.currentTimeMillis() - (60L * 60L * 1000L)); // time from which certificate is valid
    Date expiryDate = new Date(startDate.getTime() + (30L * 24L * 60L * 60L * 1000L)); // time after which certificate is not valid
    BigInteger serialNumber = serverID.toBigInteger(); // serial number for certificate

    EntityAuthentication returnAuthentication = null;

    Certificate registeredCertificate = keyStore.getCertificate(serverID.toString());
    if (registeredCertificate != null) {
        PublicKey checkKey = registeredCertificate.getPublicKey();
        PKCS10CertificationRequest certReq = new PKCS10CertificationRequest(encodedCertReq);
        if (checkKey != null) {
            byte[] encodedCheckKey = checkKey.getEncoded();
            byte[] encodedCertKey = certReq.getPublicKey().getEncoded();
            if (Arrays.equals(encodedCheckKey, encodedCertKey)) {
                X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
                X500Principal dnName = new X500Principal(
                        EntityAuthenticationClient.kEntityIDCNPrefix + serverID.toString());

                certGen.setSerialNumber(serialNumber);
                certGen.setIssuerDN(rootCertificate.getSubjectX500Principal());
                certGen.setNotBefore(startDate);
                certGen.setNotAfter(expiryDate);
                certGen.setSubjectDN(dnName); // note: same as issuer
                certGen.setPublicKey(certReq.getPublicKey());
                certGen.setSignatureAlgorithm(kCertificateSignatureAlg);

                certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,
                        new AuthorityKeyIdentifierStructure(rootCertificate));
                certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
                        new SubjectKeyIdentifierStructure(certReq.getPublicKey()));

                X509Certificate cert = certGen.generate(signingKey, "BC");
                returnAuthentication = new EntityAuthentication(cert);
            } else {
                logger.error(new ErrorLogMessage(
                        "Server {0} requesting authentication, but registered key does not match", serverID));
                throw new AuthenticationFailureException();
            }//w w  w.  j  a v  a 2 s  .  co  m
        } else {
            logger.error(new ErrorLogMessage(
                    "Server {0} requesting authentication, no check key found in registered certificate",
                    serverID));
            throw new AuthenticationFailureException();
        }
    } else {
        logger.error(new ErrorLogMessage("Server {0} requesting authentication, but not registered", serverID));
        throw new ServerNotRegisteredException();
    }
    return returnAuthentication;
}

From source file:com.rcn.service.CertificateService.java

License:Open Source License

public PublicKey fromPkcs10(String pkcs10) {
    PEMReader reader = new PEMReader(new StringReader(pkcs10), () -> new char[0], "BC");
    try {/*from  www .  ja v a2 s. co  m*/
        PKCS10CertificationRequest request = PKCS10CertificationRequest.class.cast(reader.readObject());
        return request.getPublicKey();
    } catch (Exception e) {
        throw new SecurityException(e);
    }
}

From source file:edu.washington.iam.tools.IamCertificateHelper.java

License:Apache License

public static int parseCsr(IamCertificate cert) throws IamCertificateException {

    try {//from w w  w . ja  va 2s .  co  m
        PEMReader pRd = new PEMReader(new StringReader(cert.pemRequest));
        PKCS10CertificationRequest request = (PKCS10CertificationRequest) pRd.readObject();
        if (request == null)
            throw new IamCertificateException("invalid CSR (request)");
        CertificationRequestInfo info = request.getCertificationRequestInfo();
        if (info == null)
            throw new IamCertificateException("invalid CSR (info)");

        X509Name dn = info.getSubject();
        if (dn == null)
            throw new IamCertificateException("invalid CSR (dn)");
        log.debug("dn=" + dn.toString());
        cert.dn = dn.toString();
        try {
            List cns = dn.getValues(X509Name.CN);
            cert.cn = (String) (cns.get(0));
            log.debug("cn=" + cert.cn);
            cert.names.add(cert.cn); // first entry for names is always cn
            cns = dn.getValues(X509Name.C);
            cert.dnC = (String) (cns.get(0));
            cns = dn.getValues(X509Name.ST);
            cert.dnST = (String) (cns.get(0));
        } catch (Exception e) {
            log.debug("get cn error: " + e);
            throw new IamCertificateException("invalid CSR");
        }

        // see if we've got alt names (in extensions)

        ASN1Set attrs = info.getAttributes();
        if (attrs != null) {
            for (int a = 0; a < attrs.size(); a++) {
                Attribute attr = Attribute.getInstance(attrs.getObjectAt(a));
                if (attr.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) {

                    // is the extension
                    X509Extensions extensions = X509Extensions.getInstance(attr.getAttrValues().getObjectAt(0));

                    // get the subAltName extension
                    DERObjectIdentifier sanoid = new DERObjectIdentifier(
                            X509Extensions.SubjectAlternativeName.getId());
                    X509Extension xext = extensions.getExtension(sanoid);
                    if (xext != null) {
                        log.debug("processing altname extensions");
                        ASN1Object asn1 = X509Extension.convertValueToObject(xext);
                        Enumeration dit = DERSequence.getInstance(asn1).getObjects();
                        while (dit.hasMoreElements()) {
                            GeneralName gn = GeneralName.getInstance(dit.nextElement());
                            log.debug("altname tag=" + gn.getTagNo());
                            log.debug("altname name=" + gn.getName().toString());
                            if (gn.getTagNo() == GeneralName.dNSName)
                                cert.names.add(gn.getName().toString());
                        }
                    }

                }
            }
        }

        // check key size
        PublicKey pk = request.getPublicKey();
        log.debug("key alg = " + pk.getAlgorithm());
        log.debug("key fmt = " + pk.getFormat());
        if (pk.getAlgorithm().equals("RSA")) {
            RSAPublicKey rpk = (RSAPublicKey) pk;
            cert.keySize = rpk.getModulus().bitLength();
            log.debug("key size = " + cert.keySize);
        }

    } catch (IOException e) {
        log.debug("ioerror: " + e);
        throw new IamCertificateException("invalid CSR " + e.getMessage());
    } catch (Exception e) {
        log.debug("excp: " + e);
        throw new IamCertificateException("invalid CSR");
    }
    return 1;
}

From source file:eu.optimis.ics.Credentials.CertificateGenerator.java

License:Open Source License

public static X509CertificateHolder genServerCertificate(PKCS10CertificationRequest certRequest,
        String credPath) {// ww w . j  a  va2 s  . co  m
    X509v3CertificateBuilder v3CertBuilder = null;
    ContentSigner sigGen = null;
    try {

        PEMReader r = new PEMReader(new FileReader(credPath + "ca.crt"));
        X509Certificate rootCert = (X509Certificate) r.readObject();
        r.close();

        BigInteger serial = BigInteger.ONE;

        Date notBefore = new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30);
        Date notAfter = new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365 * 10));

        SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo
                .getInstance(certRequest.getPublicKey().getEncoded());

        X500Name issuer = new X500Name(rootCert.getSubjectDN().toString());
        System.out.println(issuer.toString());
        @SuppressWarnings("deprecation")
        X500Name subject = new X500Name(certRequest.getCertificationRequestInfo().getSubject().toString());

        v3CertBuilder = new X509v3CertificateBuilder(issuer, serial, notBefore, notAfter, subject,
                publicKeyInfo);

        v3CertBuilder.addExtension(X509Extension.subjectKeyIdentifier, false,
                new SubjectKeyIdentifier(publicKeyInfo));
        v3CertBuilder.addExtension(X509Extension.authorityKeyIdentifier, false,
                new AuthorityKeyIdentifierStructure(rootCert));
        v3CertBuilder.addExtension(X509Extension.basicConstraints, false, new BasicConstraints(false));
        v3CertBuilder.addExtension(X509Extension.extendedKeyUsage, false,
                new ExtendedKeyUsage(KeyPurposeId.id_kp_serverAuth));
        v3CertBuilder.addExtension(X509Extension.keyUsage, false,
                new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment));

        sigGen = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(loadCAPrivateKey(credPath));

    } catch (IOException ioe) {
        ioe.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        e.printStackTrace();
    } catch (OperatorCreationException e) {
        e.printStackTrace();
    } catch (InvalidKeySpecException e) {
        e.printStackTrace();
    } catch (CertificateParsingException e) {
        e.printStackTrace();
    }

    return v3CertBuilder.build(sigGen);
}

From source file:eu.optimis.ics.Credentials.CertificateGenerator.java

License:Open Source License

public static X509CertificateHolder genClientCertificate(PKCS10CertificationRequest certRequest,
        String credPath) throws Exception {
    PEMReader r = new PEMReader(new FileReader(credPath + "ca.crt"));
    X509Certificate rootCert = (X509Certificate) r.readObject();
    r.close();// w  w  w  .  j a v a  2 s .  c o m

    BigInteger serial = BigInteger.valueOf(2).abs();

    Date notBefore = new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30);
    Date notAfter = new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365 * 10));

    SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo
            .getInstance(certRequest.getPublicKey().getEncoded());

    X500Name issuer = new X500Name(rootCert.getSubjectDN().toString());

    @SuppressWarnings("deprecation")
    X500Name subject = new X500Name(certRequest.getCertificationRequestInfo().getSubject().toString());

    X509v3CertificateBuilder v3CertBuilder = new X509v3CertificateBuilder(issuer, serial, notBefore, notAfter,
            subject, publicKeyInfo);

    v3CertBuilder.addExtension(X509Extension.subjectKeyIdentifier, false,
            new SubjectKeyIdentifier(publicKeyInfo));
    v3CertBuilder.addExtension(X509Extension.authorityKeyIdentifier, false,
            new AuthorityKeyIdentifierStructure(rootCert));
    v3CertBuilder.addExtension(X509Extension.basicConstraints, false, new BasicConstraints(false));
    v3CertBuilder.addExtension(X509Extension.extendedKeyUsage, false,
            new ExtendedKeyUsage(KeyPurposeId.id_kp_clientAuth));
    v3CertBuilder.addExtension(X509Extension.keyUsage, false, new KeyUsage(KeyUsage.digitalSignature));

    ContentSigner sigGen = null;

    try {
        sigGen = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(loadCAPrivateKey(credPath));
    } catch (OperatorCreationException e) {
        e.printStackTrace();
    }

    return v3CertBuilder.build(sigGen);
}

From source file:me.it_result.ca.bouncycastle.BouncyCA.java

License:Open Source License

@Override
public synchronized X509Certificate signCertificate(byte[] csrBytes) throws CAException {
    ensureInitialized();//from   ww w.  ja  v a  2  s .  co m
    try {
        PKCS10CertificationRequest csr = new PKCS10CertificationRequest(csrBytes);
        if (!csr.verify())
            throw new CAException("CSR verification failed!");
        X509Name sn = csr.getCertificationRequestInfo().getSubject();
        PublicKey publicKey = csr.getPublicKey();
        KeyStore keyStore = loadKeystore();
        PrivateKey caPrivateKey = (PrivateKey) keyStore.getKey(CA_ALIAS, keystorePassword.toCharArray());
        PublicKey caPublicKey = keyStore.getCertificate(CA_ALIAS).getPublicKey();
        BigInteger serialNumber = nextSerialNumber();
        assembleCertificate(publicKey, caPublicKey, sn.toString(), issuer, serialNumber, false, validityDays);
        ASN1Set csrAttributes = csr.getCertificationRequestInfo().getAttributes();
        Profile profile = selectProfile(csrAttributes);
        profile.generateCertificateExtensions(csrAttributes, certGen);
        X509Certificate cert = certGen.generate(caPrivateKey);
        String alias = Utils.generateAlias(sn);
        keyStore.setCertificateEntry(alias, cert);
        saveKeystore(keyStore);
        incrementSerialNumber(serialNumber);
        return cert;
    } catch (Exception e) {
        throw new CAException(e);
    } finally {
        certGen.reset();
    }
}

From source file:me.it_result.ca.CAClientTest.java

License:Open Source License

private void assertDuplicateCsrInvocation(byte[] csr, KeyPair keypair, X509Certificate certificate)
        throws Exception {
    // When generateCSR('CN=test,UID=test@test') is invoked
    byte[] newCsr = client().generateCSR(CERT_PARAMS);
    // Then a new CSR is generated for the subject name using the keypair generated earlier
    PKCS10CertificationRequest parsedCsr = new PKCS10CertificationRequest(csr);
    PKCS10CertificationRequest newParsedCsr = new PKCS10CertificationRequest(newCsr);
    assertEquals(parsedCsr.getCertificationRequestInfo().getSubject(),
            newParsedCsr.getCertificationRequestInfo().getSubject());
    assertEquals(keypair.getPublic(), parsedCsr.getPublicKey());
    // And keypair is not modified
    KeyPair newKeypair = client().getKeypair(SUBJECT_NAME);
    assertEquals(keypair.getPrivate(), newKeypair.getPrivate());
    assertEquals(keypair.getPublic(), newKeypair.getPublic());
    // And a self-signed certificate is not modified
    X509Certificate newCertificate = client().getCertificate(SUBJECT_NAME);
    assertEquals(certificate, newCertificate);
}

From source file:net.java.bd.tools.security.SecurityUtil.java

License:Open Source License

void issueCert(String csrfile, String certfile, String alias, String keypass) throws Exception {
    PKCS10CertificationRequest csr = new PKCS10CertificationRequest(convertFromBASE64(csrfile));
    String subject = csr.getCertificationRequestInfo().getSubject().toString();

    // Generate the app certificate
    X509V3CertificateGenerator cg = new X509V3CertificateGenerator();
    cg.reset();/* www.java  2 s  .  c om*/
    X509Certificate rootCert = (X509Certificate) store.getCertificate(alias);
    if (rootCert == null) {
        System.out
                .println("ERROR: Aborting application certificate creation." + " No root certificate to sign.");
        cleanup(); // removes the self signed certificate from the keystore
        System.exit(1);
    }
    cg.setIssuerDN(new X509Name(true, rootCert.getSubjectDN().getName(), new X509BDJEntryConverter()));
    cg.setSubjectDN(new X509Name(subject, new X509BDJEntryConverter()));
    cg.setNotBefore(rootCert.getNotBefore());
    cg.setNotAfter(rootCert.getNotAfter());
    cg.setPublicKey(csr.getPublicKey());
    cg.setSerialNumber(appCertSerNo);

    // BD-J mandates using SHA1WithRSA as a signature Algorithm
    cg.setSignatureAlgorithm("SHA1WITHRSA");
    cg.addExtension(X509Extensions.KeyUsage.getId(), true, new X509KeyUsage(X509KeyUsage.digitalSignature));

    // FIXME: Ideally this should be pulled out from the original app cert's
    // extension. Email on X500Name is not encoded with UTF8String.
    cg.addExtension(X509Extensions.SubjectAlternativeName.getId(), false, getRfc822Name(altName));

    // Assuming that the root certificate was generated using our tool,
    // the certificate should have IssuerAlternativeNames as an extension.
    if (rootCert.getIssuerAlternativeNames() == null) {
        System.out.println("ERROR: the root certificate must have an alternate name");
        System.exit(1);
    }
    List issuerName = (List) rootCert.getIssuerAlternativeNames().iterator().next();
    cg.addExtension(X509Extensions.IssuerAlternativeName.getId(), false,
            getRfc822Name((String) issuerName.get(1)));
    PrivateKey privateKey = (PrivateKey) store.getKey(alias, keypass.toCharArray());
    X509Certificate cert = cg.generate(privateKey);

    // Now, write leaf certificate
    System.out.println("Writing cert to " + certfile + ".");
    FileOutputStream str = new FileOutputStream(certfile);
    str.write(cert.getEncoded());
    str.close();
}

From source file:net.jxta.impl.shell.bin.pse.signcsr.java

License:Open Source License

/**
 * {@inheritDoc}//from   w w  w. j ava  2 s.  c  o m
 */
public int startApp(String[] argv) {
    ShellEnv env = getEnv();
    String issuerEnvName;
    String duration;
    String csrEnvName;

    GetOpt options = new GetOpt(argv, 0, "");

    while (true) {
        int option;
        try {
            option = options.getNextOption();
        } catch (IllegalArgumentException badopt) {
            consoleMessage("Illegal argument :" + badopt);
            return syntaxError();
        }

        if (-1 == option) {
            break;
        }

        switch (option) {

        default:
            consoleMessage("Unrecognized option");
            return syntaxError();
        }
    }

    issuerEnvName = options.getNextParameter();

    if (null == issuerEnvName) {
        consoleMessage("Missing <issuer> parameter");
        return syntaxError();
    }

    duration = options.getNextParameter();

    if (null == duration) {
        consoleMessage("Missing <duration> parameter");
        return syntaxError();
    }

    csrEnvName = options.getNextParameter();

    if (null == csrEnvName) {
        consoleMessage("Missing <csr> parameter");
        return syntaxError();
    }

    if (null != options.getNextParameter()) {
        consoleMessage("Unsupported parameter");
        return syntaxError();
    }

    MembershipService membership = getGroup().getMembershipService();

    if (!(membership instanceof PSEMembershipService)) {
        ModuleImplAdvertisement mia = (ModuleImplAdvertisement) membership.getImplAdvertisement();

        consoleMessage("Group membership service is not PSE. (" + mia.getDescription() + ")");
        return ShellApp.appMiscError;
    }

    PSEMembershipService pse = (PSEMembershipService) membership;

    if (null == pse.getDefaultCredential()) {
        consoleMessage("Key store has not been opened.");
        return ShellApp.appMiscError;
    }

    PSEUtils.IssuerInfo issuer;
    X509Certificate[] issuerChain;

    ShellObject issuerEnv = env.get(issuerEnvName);

    if (null == issuerEnv) {
        consoleMessage("Issuer environment variable '" + issuerEnvName + "' not found.");
        return ShellApp.appMiscError;
    }

    if (!PSECredential.class.isAssignableFrom(issuerEnv.getObjectClass())) {
        consoleMessage("'" + issuerEnvName + "' is not a  is not a PSE credential.");
        return ShellApp.appMiscError;
    }

    PSECredential cred = (PSECredential) issuerEnv.getObject();

    issuerChain = cred.getCertificateChain();

    PrivateKey issuerKey = null;

    try {
        issuerKey = cred.getPrivateKey();
    } catch (IllegalStateException notLocal) {
        //ignored            
    }

    if (null == issuerKey) {
        consoleMessage("Credential is not a local login credential.");
        return ShellApp.appMiscError;
    }

    issuer = new PSEUtils.IssuerInfo();

    issuer.cert = issuerChain[0];
    issuer.subjectPkey = issuerKey;

    ShellObject csrEnv = env.get(csrEnvName);

    if (null == csrEnv) {
        consoleMessage("CSR environment variable not found.");
        return ShellApp.appMiscError;
    }

    if (!StructuredDocument.class.isAssignableFrom(csrEnv.getObjectClass())) {
        consoleMessage("'" + csrEnvName + "' is not a Certificate Signing Request.");
        return ShellApp.appMiscError;
    }

    net.jxta.impl.protocol.CertificateSigningRequest csr_msg = new net.jxta.impl.protocol.CertificateSigningRequest(
            (Element) csrEnv.getObject());

    org.bouncycastle.jce.PKCS10CertificationRequest csr = csr_msg.getCSR();

    // set validity 10 years from today
    Date today = new Date();
    Calendar cal = Calendar.getInstance();
    cal.setTime(today);
    cal.add(Calendar.DATE, Integer.parseInt(duration));
    Date until = cal.getTime();

    // generate cert
    try {
        X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();

        certGen.setIssuerDN(new X509Principal(true, issuer.cert.getSubjectX500Principal().getName()));
        certGen.setSubjectDN(csr.getCertificationRequestInfo().getSubject());
        certGen.setNotBefore(today);
        certGen.setNotAfter(until);
        certGen.setPublicKey(csr.getPublicKey());
        //certGen.setSignatureAlgorithm("SHA1withDSA");
        certGen.setSignatureAlgorithm("SHA1withRSA");
        // FIXME bondolo 20040317 needs fixing.
        certGen.setSerialNumber(BigInteger.valueOf(1));

        // return issuer info for generating service cert

        // the cert
        X509Certificate newCert = certGen.generateX509Certificate(issuer.subjectPkey);

        net.jxta.impl.protocol.Certificate cert_msg = new net.jxta.impl.protocol.Certificate();

        List<X509Certificate> newChain = new ArrayList<X509Certificate>(Arrays.asList(issuerChain));

        newChain.add(0, newCert);

        cert_msg.setCertificates(newChain);

        XMLDocument asXML = (XMLDocument) cert_msg.getDocument(MimeMediaType.XMLUTF8);

        ShellObject<XMLDocument> newObj = new ShellObject<XMLDocument>("Certificate", asXML);
        env.add(getReturnVariable(), newObj);
    } catch (Exception failed) {
        printStackTrace("Failed to generate certificate", failed);
    }

    return ShellApp.appNoError;
}