private static String csr() {
    try {
      KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
      keyGen.initialize(2048);
      KeyPair keyPair = keyGen.generateKeyPair();
      X500Principal subject =
          new X500Principal(
              "CN = edea87b4-034d-48dc-94dd-e7cdcfdde370/10562468, OU = fgdfgretertgdfg, O = VW, L = US");
      ContentSigner signer = new JcaContentSignerBuilder("SHA1withRSA").build(keyPair.getPrivate());
      PKCS10CertificationRequestBuilder builder =
          new JcaPKCS10CertificationRequestBuilder(subject, keyPair.getPublic());
      PKCS10CertificationRequest csr = builder.build(signer);

      String type = "CERTIFICATE REQUEST";
      PemObject pem = new PemObject(type, csr.getEncoded());
      StringWriter str = new StringWriter();
      PEMWriter pemWriter = new PEMWriter(str);
      pemWriter.writeObject(pem);
      pemWriter.close();
      str.close();
      Log.d("Test", "" + str);
      return Base64Util.getStringAsBase64(str.toString());
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (OperatorCreationException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return "";
  }
  @Test
  public void shouldBuildParseEncodedRpkiCaCertRequest() throws Exception {

    PKCS10CertificationRequest pkcs10Request = createRpkiCaCertificateRequest();

    assertNotNull(pkcs10Request);

    PKCS10CertificationRequest decodedPkcs10Request =
        new PKCS10CertificationRequest(pkcs10Request.getEncoded());

    RpkiCaCertificateRequestParser requestParser =
        new RpkiCaCertificateRequestParser(decodedPkcs10Request);

    Assert.assertEquals(
        ProvisioningObjectMother.RPKI_CA_CERT_REQUEST_CA_REPO_URI,
        requestParser.getCaRepositoryUri());
    Assert.assertEquals(
        ProvisioningObjectMother.RPKI_CA_CERT_REQUEST_CA_MFT_URI, requestParser.getManifestUri());
    Assert.assertEquals(
        ProvisioningObjectMother.RPKI_CA_CERT_REQUEST_CA_NOTIFICATION_URI,
        requestParser.getNotificationUri());
    Assert.assertEquals(
        ProvisioningObjectMother.RPKI_CA_CERT_REQUEST_KEYPAIR.getPublic(),
        requestParser.getPublicKey());
  }
  /**
   * Generate a certificate signing request (PKCS#10).
   *
   * @param info A PKCS10CertReqInfo
   * @param privateKey Private key for signing the request
   * @param signatureProvider Name of provider to sign with
   * @param publicKey Public key to include in the request
   * @param explicitEccParameters True if the EC domain parameters should be included (ie. not a
   *     named curve)
   * @return the certificate request data
   */
  public static ICertReqData genCertificateRequest(
      ISignerCertReqInfo info,
      final PrivateKey privateKey,
      final String signatureProvider,
      PublicKey publicKey,
      final boolean explicitEccParameters)
      throws IllegalArgumentException {
    LOG.debug(">genCertificateRequest");
    final Base64SignerCertReqData retval;
    if (info instanceof PKCS10CertReqInfo) {
      PKCS10CertReqInfo reqInfo = (PKCS10CertReqInfo) info;
      PKCS10CertificationRequest pkcs10;

      if (LOG.isDebugEnabled()) {
        LOG.debug("signatureAlgorithm: " + reqInfo.getSignatureAlgorithm());
        LOG.debug("subjectDN: " + reqInfo.getSubjectDN());
        LOG.debug("explicitEccParameters: " + explicitEccParameters);
      }

      try {
        // Handle ECDSA key with explicit parameters
        if (explicitEccParameters && publicKey.getAlgorithm().contains("EC")) {
          publicKey = ECKeyUtil.publicToExplicitParameters(publicKey, "BC");
        }

        if (LOG.isDebugEnabled()) {
          LOG.debug("Public key SHA1: " + createKeyHash(publicKey));
          LOG.debug("Public key SHA256: " + KeyUsageCounterHash.create(publicKey));
        }

        // Generate request
        final JcaPKCS10CertificationRequestBuilder builder =
            new JcaPKCS10CertificationRequestBuilder(
                new X500Name(CertTools.stringToBCDNString(reqInfo.getSubjectDN())), publicKey);
        final ContentSigner contentSigner =
            new JcaContentSignerBuilder(reqInfo.getSignatureAlgorithm())
                .setProvider(signatureProvider)
                .build(privateKey);
        pkcs10 = builder.build(contentSigner);
        retval = new Base64SignerCertReqData(Base64.encode(pkcs10.getEncoded()));
      } catch (IOException e) {
        throw new IllegalArgumentException("Certificate request error: " + e.getMessage(), e);
      } catch (OperatorCreationException e) {
        throw new IllegalArgumentException("Certificate request error: " + e.getMessage(), e);
      } catch (NoSuchAlgorithmException e) {
        throw new IllegalArgumentException("Certificate request error: " + e.getMessage(), e);
      } catch (NoSuchProviderException e) {
        throw new IllegalArgumentException("Certificate request error: " + e.getMessage(), e);
      }
      LOG.debug("<genCertificateRequest");
      return retval;
    } else {
      throw new IllegalArgumentException(
          "Unsupported certificate request info type: " + info.getClass().getName());
    }
  }
  @Override
  protected Object _doExecute() throws Exception {
    P10RequestGenerator p10Gen = new P10RequestGenerator();

    hashAlgo = hashAlgo.trim().toUpperCase();
    if (hashAlgo.indexOf('-') != -1) {
      hashAlgo = hashAlgo.replaceAll("-", "");
    }

    if (needExtensionTypes == null) {
      needExtensionTypes = new LinkedList<>();
    }

    // SubjectAltNames
    List<Extension> extensions = new LinkedList<>();
    if (isNotEmpty(subjectAltNames)) {
      extensions.add(P10RequestGenerator.createExtensionSubjectAltName(subjectAltNames, false));
      needExtensionTypes.add(Extension.subjectAlternativeName.getId());
    }

    // SubjectInfoAccess
    if (isNotEmpty(subjectInfoAccesses)) {
      extensions.add(
          P10RequestGenerator.createExtensionSubjectInfoAccess(subjectInfoAccesses, false));
      needExtensionTypes.add(Extension.subjectInfoAccess.getId());
    }

    // Keyusage
    if (isNotEmpty(keyusages)) {
      Set<KeyUsage> usages = new HashSet<>();
      for (String usage : keyusages) {
        usages.add(KeyUsage.getKeyUsage(usage));
      }
      org.bouncycastle.asn1.x509.KeyUsage extValue = X509Util.createKeyUsage(usages);
      ASN1ObjectIdentifier extType = Extension.keyUsage;
      extensions.add(new Extension(extType, false, extValue.getEncoded()));
      needExtensionTypes.add(extType.getId());
    }

    // ExtendedKeyusage
    if (isNotEmpty(extkeyusages)) {
      Set<ASN1ObjectIdentifier> oids =
          new HashSet<>(SecurityUtil.textToASN1ObjectIdentifers(extkeyusages));
      ExtendedKeyUsage extValue = X509Util.createExtendedUsage(oids);
      ASN1ObjectIdentifier extType = Extension.extendedKeyUsage;
      extensions.add(new Extension(extType, false, extValue.getEncoded()));
      needExtensionTypes.add(extType.getId());
    }

    // QcEuLimitValue
    if (isNotEmpty(qcEuLimits)) {
      ASN1EncodableVector v = new ASN1EncodableVector();
      for (String m : qcEuLimits) {
        StringTokenizer st = new StringTokenizer(m, ":");
        try {
          String currencyS = st.nextToken();
          String amountS = st.nextToken();
          String exponentS = st.nextToken();

          Iso4217CurrencyCode currency;
          try {
            int intValue = Integer.parseInt(currencyS);
            currency = new Iso4217CurrencyCode(intValue);
          } catch (NumberFormatException e) {
            currency = new Iso4217CurrencyCode(currencyS);
          }

          int amount = Integer.parseInt(amountS);
          int exponent = Integer.parseInt(exponentS);

          MonetaryValue monterayValue = new MonetaryValue(currency, amount, exponent);
          QCStatement statment =
              new QCStatement(ObjectIdentifiers.id_etsi_qcs_QcLimitValue, monterayValue);
          v.add(statment);
        } catch (Exception e) {
          throw new Exception("invalid qc-eu-limit '" + m + "'");
        }
      }

      ASN1ObjectIdentifier extType = Extension.qCStatements;
      ASN1Sequence extValue = new DERSequence(v);
      extensions.add(new Extension(extType, false, extValue.getEncoded()));
      needExtensionTypes.add(extType.getId());
    }

    // biometricInfo
    if (biometricType != null && biometricHashAlgo != null && biometricFile != null) {
      TypeOfBiometricData _biometricType;
      if (StringUtil.isNumber(biometricType)) {
        _biometricType = new TypeOfBiometricData(Integer.parseInt(biometricType));
      } else {
        _biometricType = new TypeOfBiometricData(new ASN1ObjectIdentifier(biometricType));
      }

      ASN1ObjectIdentifier _biometricHashAlgo = AlgorithmUtil.getHashAlg(biometricHashAlgo);
      byte[] biometricBytes = IoUtil.read(biometricFile);
      MessageDigest md = MessageDigest.getInstance(_biometricHashAlgo.getId());
      md.reset();
      byte[] _biometricDataHash = md.digest(biometricBytes);

      DERIA5String _sourceDataUri = null;
      if (biometricUri != null) {
        _sourceDataUri = new DERIA5String(biometricUri);
      }
      BiometricData biometricData =
          new BiometricData(
              _biometricType,
              new AlgorithmIdentifier(_biometricHashAlgo),
              new DEROctetString(_biometricDataHash),
              _sourceDataUri);

      ASN1EncodableVector v = new ASN1EncodableVector();
      v.add(biometricData);

      ASN1ObjectIdentifier extType = Extension.biometricInfo;
      ASN1Sequence extValue = new DERSequence(v);
      extensions.add(new Extension(extType, false, extValue.getEncoded()));
      needExtensionTypes.add(extType.getId());
    } else if (biometricType == null && biometricHashAlgo == null && biometricFile == null) {
      // Do nothing
    } else {
      throw new Exception(
          "either all of biometric triples (type, hash algo, file)"
              + " must be set or none of them should be set");
    }

    if (isNotEmpty(needExtensionTypes) || isNotEmpty(wantExtensionTypes)) {
      ExtensionExistence ee =
          new ExtensionExistence(
              SecurityUtil.textToASN1ObjectIdentifers(needExtensionTypes),
              SecurityUtil.textToASN1ObjectIdentifers(wantExtensionTypes));
      extensions.add(
          new Extension(
              ObjectIdentifiers.id_xipki_ext_cmpRequestExtensions,
              false,
              ee.toASN1Primitive().getEncoded()));
    }

    ConcurrentContentSigner identifiedSigner =
        getSigner(hashAlgo, new SignatureAlgoControl(rsaMgf1, dsaPlain));
    Certificate cert = Certificate.getInstance(identifiedSigner.getCertificate().getEncoded());

    X500Name subjectDN;
    if (subject != null) {
      subjectDN = getSubject(subject);
    } else {
      subjectDN = cert.getSubject();
    }

    SubjectPublicKeyInfo subjectPublicKeyInfo = cert.getSubjectPublicKeyInfo();

    ContentSigner signer = identifiedSigner.borrowContentSigner();

    PKCS10CertificationRequest p10Req;
    try {
      p10Req = p10Gen.generateRequest(signer, subjectPublicKeyInfo, subjectDN, extensions);
    } finally {
      identifiedSigner.returnContentSigner(signer);
    }

    File file = new File(outputFilename);
    saveVerbose("saved PKCS#10 request to file", file, p10Req.getEncoded());
    return null;
  }