I need help to setup an application in android using eclipse.
I have not used eclipse for JAVA development before so I am a little green as to how this all comes together with android in the mix.
I have a script that I downloaded to test with my web server that has been setup to produce output when accessed (JSON named value pairs at this time).
I am using -
Eclipse IDE for Java Developers
Version: Helios Service Release 2
Build id: 20110218-0911
Android Development Toolkit
Version: 10.0.1.v201103111512-110841
The JAVA code so far -
package new.android.test;
import android.app.Activity;
import android.os.Bundle;
import java.io.ByteArrayInputStream;
import java.net.Socket;
import org.apache.http.ConnectionReuseStrategy;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpClientConnection;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.params.SyncBasicHttpParams;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.HttpRequestExecutor;
import org.apache.http.protocol.ImmutableHttpProcessor;
import org.apache.http.protocol.RequestConnControl;
import org.apache.http.protocol.RequestContent;
import org.apache.http.protocol.RequestExpectContinue;
import org.apache.http.protocol.RequestTargetHost;
import org.apache.http.protocol.RequestUserAgent;
import org.apache.http.util.EntityUtils;
/**
* Elemental example for executing a POST request.
* <p>
* Please note the purpose of this application is demonstrate the usage of HttpCore APIs.
* It is NOT intended to demonstrate the most efficient way of building an HTTP client.
*
*
*
*/
public class search extends Activity {
public static void main(String[] args) throws Exception {
HttpParams params = new SyncBasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, "UTF-8");
HttpProtocolParams.setUserAgent(params, "HttpComponents/1.1");
HttpProtocolParams.setUseExpectContinue(params, true);
HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
// Required protocol interceptors
new RequestContent(),
new RequestTargetHost(),
// Recommended protocol interceptors
new RequestConnControl(),
new RequestUserAgent(),
new RequestExpectContinue()});
HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
HttpContext context = new BasicHttpContext(null);
HttpHost host = new HttpHost("localhost", 80);
DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
ConnectionReuseStrategy connStrategy = new DefaultConnectionReuseStrategy();
context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
try {
HttpEntity[] requestBodies = {
new StringEntity(
"This is the first test request", "UTF-8"),
new ByteArrayEntity(
"This is the second test request".getBytes("UTF-8")),
new InputStreamEntity(
new ByteArrayInputStream(
"This is the third test request (will be chunked)"
.getBytes("UTF-8")), -1)
};
for (int i = 0; i < requestBodies.length; i++) {
if (!conn.isOpen()) {
Socket socket = new Socket(host.getHostName(), host.getPort());
conn.bind(socket, params);
}
BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST",
"/android.php");
request.setEntity(requestBodies[i]);
System.out.println(">> Request URI: " + request.getRequestLine().getUri());
request.setParams(params);
httpexecutor.preProcess(request, httpproc, context);
HttpResponse response = httpexecutor.execute(request, conn, context);
response.setParams(params);
httpexecutor.postProcess(response, httpproc, context);
System.out.println("<< Response: " + response.getStatusLine());
System.out.println(EntityUtils.toString(response.getEntity()));
System.out.println("==============");
if (!connStrategy.keepAlive(response, context)) {
conn.close();
} else {
System.out.println("Connection kept alive...");
}
}
} finally {
conn.close();
}
}
}
Ok main question is why so many imports?
Also I am getting errors for these imports:
The import org.apache.http.params.SyncBasicHttpParams cannot be resolved
The import org.apache.http.protocol.ImmutableHttpProcessor cannot be resolved
I cannot see these classes in the android.jar.
Is there a more simple example of implementing a transaction against a web server to obtain a namevaluepair (JSON) for using in the android java application?
Those errors are because the classes you are referencing are not a part of the standard Android distribution: see http://developer.android.com/reference/org/apache/http/params/package-summary.html and http://developer.android.com/reference/org/apache/http/protocol/package-summary.html.
Android repackages a specific version of the Apache HTTP library. If you want to use those classes you'll need to include those jars.
Related
How to run the below Appium code in sauce labs? When I checked sauce labs website there is only one line given below
driver = new WebDriver(
new URL("https://balajimscit09:a30f3417-cbe6-48ce-92b5-e9a6d0814879#ondemand.us-west-1.saucelabs.com:443")
);
Below is my code
package mobile_Appium;
import static io.appium.java_client.touch.TapOptions.tapOptions;
import static io.appium.java_client.touch.WaitOptions.waitOptions;
import static io.appium.java_client.touch.offset.ElementOption.element;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.FindsByAndroidUIAutomator;
import io.appium.java_client.MobileElement;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidTouchAction;
import io.appium.java_client.remote.MobileCapabilityType;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
public class InstallTestAndroid10 {
static AppiumDriver driver;
public static void main(String[] args) throws MalformedURLException, InterruptedException {
File f = new File("src");
File fs = new File(f, "ApiDemos-debug.apk");
DesiredCapabilities cap = new DesiredCapabilities();
cap.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
cap.setCapability(MobileCapabilityType.VERSION, "10.0");
cap.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Device");
cap.setCapability(MobileCapabilityType.AUTOMATION_NAME, "Uiautomator2");
cap.setCapability("autoGrantPermissions", true);
cap.setCapability("noReset", "false");
cap.setCapability("fullReset", "true");
cap.setCapability(MobileCapabilityType.APP, fs.getAbsolutePath());
driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), cap);
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
/*driver.findElement(By.xpath("//android.widget.Button[#text='OK']")).click();
Thread.sleep(10000);
((FindsByAndroidUIAutomator<MobileElement>) driver).findElementByAndroidUIAutomator("new UiScrollable(new UiSelector().scrollable(true).instance(0)).scrollIntoView(new UiSelector().textContains(\"Views\").instance(0))");
driver.findElement(By.xpath("//android.widget.TextView[#text='Views']")).click(); */
}}
How to integrate with a real device present in sauce labs?
Your App should be upload to sauce storage.
After that, the app capability should point to this file.
Fo example:
cap.setCapability(MobileCapabilityType.APP, "storage:filename=ApiDemos-debug.apk");
You can read more here:
https://wiki.saucelabs.com/display/DOCS/Application+Storage
Also, you should change your access key after publishing it here
In those capabilities, it looks like you are still pointing to a local URL. You need to add a URL for sauce labs with your username and access key, and upload an app. See how it is done in this video: https://www.youtube.com/watch?v=hwp5YeF5Me4
There are 3 basic things that you need to do to run an Appium test
Upload your app to Sauce Labs so your test can run against it in the Real Device Cloud
Update your Test code with your Sauce Username and Access Key (Set as environment vars), and use these to start a driver with the endpoint (or URL) to test against
Update your capabilities for the real device you want to test including app name, device, platform version and more.
System.out.println("Sauce iOS Native - BeforeMethod hook");
String username = System.getenv("SAUCE_USERNAME");
String accesskey = System.getenv("SAUCE_ACCESS_KEY");
String sauceUrl;
if (region.equalsIgnoreCase("eu")) {
sauceUrl = "#ondemand.eu-central-1.saucelabs.com:443";
} else {
sauceUrl = "#ondemand.us-west-1.saucelabs.com:443";
}
String SAUCE_REMOTE_URL = "https://" + username + ":" + accesskey + sauceUrl +"/wd/hub";
String appName = "iOS.RealDevice.SauceLabs.Mobile.Sample.app.2.7.1.ipa";
String methodName = method.getName();
URL url = new URL(SAUCE_REMOTE_URL);
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceName", "iPhone 8.*");
capabilities.setCapability("platformName", "iOS");
capabilities.setCapability("automationName", "XCuiTest");
capabilities.setCapability("app", "storage:filename="+appName); // or "storage:"+appID
capabilities.setCapability("name", methodName);
iosDriver.set(new IOSDriver(url, capabilities));
I have a working uploaded ML-model on Goggle Cloud platform (Tested via python and gcloud ml-engine predict).
I am currently trying to get predictions from Android using this library: Client Library for Java with this javadoc.
I use a service account for access and Android code in a AsyncTask that looks like this:
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
HttpTransport httpTransport = new com.google.api.client.http.javanet.NetHttpTransport();
GoogleCredential credential = GoogleCredential.fromStream(is, httpTransport, jsonFactory);
CloudMachineLearningEngine ml = new CloudMachineLearningEngine.Builder(httpTransport,jsonFactory,credential)
.setApplicationName("myCloudApplication")
.build();
Log.i(TAG,"Successfully set up !!");
is is the InputStream to the json file containing my Service Account Key.
I have tried many things getting from here to make predictions against my trained ML-model. I can't find any online examples.
Is this even possible?
All help is deeply appreciated.
This is definitely supported. From this sample:
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpContent;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.UriTemplate;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.discovery.Discovery;
import com.google.api.services.discovery.model.JsonSchema;
import com.google.api.services.discovery.model.RestDescription;
import com.google.api.services.discovery.model.RestMethod;
import java.io.File;
/*
* Sample code for doing Cloud Machine Learning Engine online prediction in Java.
*/
public class OnlinePredictionSample {
public static void main(String[] args) throws Exception {
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
Discovery discovery = new Discovery.Builder(httpTransport, jsonFactory, null).build();
RestDescription api = discovery.apis().getRest("ml", "v1").execute();
RestMethod method = api.getResources().get("projects").getMethods().get("predict");
JsonSchema param = new JsonSchema();
String projectId = "YOUR_PROJECT_ID";
// You should have already deployed a model and a version.
// For reference, see https://cloud.google.com/ml-engine/docs/how-tos/deploying-models.
String modelId = "YOUR_MODEL_ID";
String versionId = "YOUR_VERSION_ID";
param.set(
"name", String.format("projects/%s/models/%s/versions/%s", projectId, modelId, versionId));
GenericUrl url =
new GenericUrl(UriTemplate.expand(api.getBaseUrl() + method.getPath(), param, true));
System.out.println(url);
String contentType = "application/json";
File requestBodyFile = new File("input.txt");
HttpContent content = new FileContent(contentType, requestBodyFile);
System.out.println(content.getLength());
GoogleCredential credential = GoogleCredential.getApplicationDefault();
HttpRequestFactory requestFactory = httpTransport.createRequestFactory(credential);
HttpRequest request = requestFactory.buildRequest(method.getHttpMethod(), url, content);
String response = request.execute().parseAsString();
System.out.println(response);
}
}
I am automating mobile web application using Appium Server and Selenium.
All I want to do is to retrieve the titles of android notification, to achieve this i tried to using the locator: findElementsByAndroidUIAutomator to identify an element using resourceId.
Below is the code written by me:
package com.roofandfloor.test;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.MobileBy;
import io.appium.java_client.android.AndroidDriver;
public class test02 {
public static void main(String[] args) throws MalformedURLException, InterruptedException {
DesiredCapabilities desc = null;
URL url = null;
desc = new DesiredCapabilities();
desc.setCapability("automationName","Appium");
desc.setCapability("platformName", "Android");
desc.setCapability("platformVersion", "5.0");
desc.setCapability("deviceName", "Lenovo K50a40");
desc.setCapability("browserName", "Chrome");
desc.setCapability("appPackage", "com.android.chrome");
desc.setCapability("appActivity", "com.google.android.apps.chrome.Main");
url = new URL("http://0.0.0.0:4723/wd/hub");
AndroidDriver driver = new AndroidDriver(url,desc);
driver.openNotifications();
Thread.sleep(5000);
List<WebElement>allNotifications=driver.findElementsByAndroidUIAutomator("new UiSelector().resourceId(\"android:id/title\")");
System.out.println(allNotifications.size());
}
}
When I run the above code I am getting the error shown below:
org.openqa.selenium.WebDriverException: unknown error: Unsupported locator strategy: -android uiautomator
I have alternatively tried to use the below code.
List<WebElement>allNotifications=driver.findElements(MobileBy.AndroidUIAutomator("new UiSelector().resourceId(\"android:id/title\")"));
I am getting the same error as above.
Please help me resolving the issue.
I have windows 7 which is connected to two android devices and I am using Selenium and Appium to automate an App but not able to run the test simultaneously in both the devices. below is the code I am using along with contents from testng.xml. let me know where I am wrong. The below code runs fine but it installs the app on first device then on second device what I want to acheive is install the app simultaneously on both the devices. Any help appreciated.
package ca.automation.com;
import org.testng.annotations.Test;
import com.relevantcodes.extentreports.ExtentReports;
import com.relevantcodes.extentreports.ExtentTest;
import com.relevantcodes.extentreports.LogStatus;
import io.appium.java_client.android.AndroidDriver;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class StackOverflow {
WebDriver driver1;
WebDriver driver2;
// ExtentReports report;
// ExtentTest logger;
// Boolean present;
File app = new File("App\\app_US_IT_Ananta.apk");
#BeforeSuite
public void startReport(){
// report=new ExtentReports("C:\\Anuj\\MobileAppResults.html");
}
#Test (priority =0)
public void installapp() {
// logger=report.startTest("VerifyAppInstalltion");
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("udid", "1015fadb1a274005");
// capabilities.setCapability("udid", "ee92ba92");
capabilities.setCapability("deviceName","Android Emulator");
capabilities.setCapability("platformVersion", "4.4");
capabilities.setCapability("autoAcceptAlerts", true);
capabilities.setCapability("app", app.getAbsolutePath());
try {
driver1 = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
#Test (priority =0)
public void installapp1() {
DesiredCapabilities capabilities1 = new DesiredCapabilities();
capabilities1.setCapability("udid", "ee92ba92");
capabilities1.setCapability("deviceName","Android Emulator");
capabilities1.setCapability("platformVersion", "4.4");
capabilities1.setCapability("autoAcceptAlerts", true);
capabilities1.setCapability("app", app.getAbsolutePath());
try {
driver2 = new AndroidDriver(new URL("http://127.0.0.1:4730/wd/hub"), capabilities1);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
Testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="tests" thread-count="2">
<test name="Test">
<classes>
<class name="ca.automation.com.StackOverflow"/>
</classes>
</test> <!-- Test -->
Change parallel="tests" to parallel="methods" because you have to execute the methods in parallel, as its in your case.
Also, running tests in parallel wont be exactly 100% simultaneous execution. There would be some lag between execution in both devices. Try out a complete script with few more additional steps. That way we can easily make out that the tests are running simultaneously.
I am trying to use Spongy Castle (v1.47) to create a PKCS10 Certification Request. Spongy Castle behaves exactly the same way as Bouncy Castle, but is more suited to port on Android.
The old (depricated) way as described in Beginning Cryptography with Java by David Hook in chapter 6 works just fine:
package chapter6;
import java.io.OutputStreamWriter;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.util.Vector;
import javax.security.auth.x500.X500Principal;
import org.spongycastle.asn1.DEROctetString;
import org.spongycastle.asn1.DERSet;
import org.spongycastle.asn1.pkcs.Attribute;
import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.spongycastle.asn1.x509.GeneralName;
import org.spongycastle.asn1.x509.GeneralNames;
import org.spongycastle.asn1.x509.X509Extension;
import org.spongycastle.asn1.x509.X509Extensions;
import org.spongycastle.jce.PKCS10CertificationRequest;
import org.spongycastle.openssl.PEMWriter;
import org.spongycastle.jce.provider.BouncyCastleProvider;
/**
* Generation of a basic PKCS #10 request with an extension.
*/
public class PKCS10ExtensionExample {
static {
BouncyCastleProvider prov = new org.spongycastle.jce.provider.BouncyCastleProvider();
Security.addProvider(prov);
}
public static PKCS10CertificationRequest generateRequest( KeyPair pair) throws Exception {
// create a SubjectAlternativeName extension value
GeneralNames subjectAltName = new GeneralNames(new GeneralName(GeneralName.rfc822Name, "test#test.test"));
// create the extensions object and add it as an attribute
Vector oids = new Vector();
Vector values = new Vector();
oids.add(X509Extensions.SubjectAlternativeName);
values.add(new X509Extension(false, new DEROctetString(subjectAltName)));
X509Extensions extensions = new X509Extensions(oids, values);
Attribute attribute = new Attribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, new DERSet(extensions));
return new PKCS10CertificationRequest(
"SHA256withRSA",
new X500Principal("CN=Requested Test Certificate"),
pair.getPublic(),
new DERSet(attribute),
pair.getPrivate());
}
public static void main(String[] args) throws Exception {
// create the keys
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "SC");
kpGen.initialize(1024, Utils.createFixedRandom());
KeyPair pair = kpGen.generateKeyPair();
PKCS10CertificationRequest request = generateRequest(pair);
PEMWriter pemWrt = new PEMWriter(new OutputStreamWriter(System.out));
pemWrt.writeObject(request);
pemWrt.close();
}
}
The small java program prints out the following:
-----BEGIN CERTIFICATE REQUEST-----
MIIBkDCB+gIBADAlMSMwIQYDVQQDExpSZXF1ZXN0ZWQgVGVzdCBDZXJ0aWZpY2F0
ZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAm38mHcNo+YDhe1/XHRa1Cifj
EUwH6SQfqKQcY0sO4gGTVL/U5kBx/y0gIptrnGgUYgfwqptWoKHIqd4PGAuzHfwI
QrTfnYtLnN3dBdnOx/1mZuJ/fCD48H45sTVCcXbypxdwns2PZwgh1rt+jb7TJQii
5TteCLvzzb7FVb/Oc6MCAwEAAaAsMCoGCSqGSIb3DQEJDjEdMBswGQYDVR0RBBIw
EIEOdGVzdEB0ZXN0LnRlc3QwDQYJKoZIhvcNAQELBQADgYEAJexpAYF6RvbYGiNS
kyaF1H8TpDOHaAuIvS4G2Kqw9xXJHYEDiNsQxMc4gWdx6ZNDzc1JYqFBaEV+c/zt
pRPLTRxTi841tLBUAzX7eFQ5EtLwJrKLlHCMXxg3DwcrPjRwidcE87Nl/sOyeT4K
btCXzqpLtklJi/giBl/4L+lQunU=
-----END CERTIFICATE REQUEST-----
The problem is that in the meanwhile (the book is from 2005) most of this Classes are marked as depricated. The new way of creating certificate signing requests is by using Factory Patterns:
package chapter6;
import java.io.OutputStreamWriter;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.util.Vector;
import org.spongycastle.asn1.DERPrintableString;
import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.spongycastle.asn1.x500.X500Name;
import org.spongycastle.asn1.x509.ExtendedKeyUsage;
import org.spongycastle.asn1.x509.KeyPurposeId;
import org.spongycastle.asn1.x509.KeyUsage;
import org.spongycastle.asn1.x509.SubjectPublicKeyInfo;
import org.spongycastle.asn1.x509.X509Extension;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import org.spongycastle.openssl.PEMWriter;
import org.spongycastle.operator.ContentSigner;
import org.spongycastle.operator.ContentVerifierProvider;
import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
import org.spongycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
import org.spongycastle.pkcs.PKCS10CertificationRequest;
import org.spongycastle.pkcs.PKCS10CertificationRequestBuilder;
/**
* Generation of a basic PKCS #10 request with an extension.
*/
public class PKCS10ExtensionExampleNew {
static {
BouncyCastleProvider prov = new org.spongycastle.jce.provider.BouncyCastleProvider();
Security.addProvider(prov);
}
public static PKCS10CertificationRequest generateRequest(KeyPair pair) throws Exception {
SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(pair.getPublic().getEncoded());
X500Name subject = new X500Name("CN=Requested Test Certificate");
PKCS10CertificationRequestBuilder certificationRequestBuilder = new PKCS10CertificationRequestBuilder(subject, publicKeyInfo);
certificationRequestBuilder.addAttribute(X509Extension.keyUsage,
new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.dataEncipherment | KeyUsage.keyAgreement));
Vector<KeyPurposeId> ekUsages = new Vector<KeyPurposeId>();
ekUsages.add(KeyPurposeId.id_kp_clientAuth);
ekUsages.add(KeyPurposeId.id_kp_serverAuth);
certificationRequestBuilder.addAttribute(X509Extension.extendedKeyUsage, new ExtendedKeyUsage(ekUsages));
JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder("SHA1WithRSAEncryption");
contentSignerBuilder.setProvider("SC");
ContentSigner contentSigner = contentSignerBuilder.build(pair.getPrivate());
DERPrintableString password = new DERPrintableString("secret123");
certificationRequestBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_challengePassword, password);
PKCS10CertificationRequest certificationRequest = certificationRequestBuilder.build(contentSigner);
JcaContentVerifierProviderBuilder contentVerifierProviderBuilder = new JcaContentVerifierProviderBuilder();
ContentVerifierProvider contentVerifierProvider = contentVerifierProviderBuilder.build(pair.getPublic());
System.out.println("isSignatureValid? " + certificationRequest.isSignatureValid(contentVerifierProvider));
System.out.println(certificationRequest.getSubject());
return certificationRequest;
}
public static void main(String[] args) throws Exception {
// create the keys
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "SC");
kpGen.initialize(1024, Utils.createFixedRandom());
KeyPair pair = kpGen.generateKeyPair();
PKCS10CertificationRequest request = generateRequest(pair);
PEMWriter pemWrt = new PEMWriter(new OutputStreamWriter(System.out));
pemWrt.writeObject(request);
pemWrt.close();
}
}
The Certificate Request does not get properly build, as it fails on the PEM Generation:
isSignatureValid? true
CN=Requested Test Certificate
Exception in thread "main" org.spongycastle.util.io.pem.PemGenerationException: unknown object passed - can't encode.
at org.spongycastle.openssl.MiscPEMGenerator.createPemObject(MiscPEMGenerator.java:208)
at org.spongycastle.openssl.MiscPEMGenerator.generate(MiscPEMGenerator.java:333)
at org.spongycastle.util.io.pem.PemWriter.writeObject(PemWriter.java:76)
at org.spongycastle.openssl.PEMWriter.writeObject(PEMWriter.java:45)
at be.boeboe.spongycastle.chapter6.PKCS10ExtensionExampleNew.main(PKCS10ExtensionExampleNew.java:71)
Anyone has any idea why the second attempt to create a request failed? I created X509V3Certificate certificates both the old and new way and had no problem there, but putting those differences next to the ones shown here, didn't make me any wiser.
Any help kindly appreciated.
Boeboe