Getting Appium Driver "Null pointer exception" - android

I have been working on appium with Selenium and Testng from some time. I was able to execute my script without this null pointer error till yesterday. Can anyone tell me what's wrong with my script.
package testCases;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
import org.testng.Assert;
import io.appium.java_client.MobileElement;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import utilities.Constant;
import utilities.ExcelUtils;
import pageObjects.DearoLoginPage;
import pageObjects.JobCardsPage;
import TestData.MongoDBConnector;
import utilities.AndroidAppSetup;
public class Main_TestCase {
AndroidDriver<MobileElement> driver;
DearoLoginPage objLogin = new DearoLoginPage(driver);
MongoDBConnector objDB = new MongoDBConnector();
AndroidAppSetup objAndroidAppSetup = new AndroidAppSetup();
#BeforeClass
public void setUp() throws Exception{
//This is to open the Excel file. Excel path, file name and the sheet name are parameters to this method
ExcelUtils.setExcelFileSheet(Constant.Path_TestData+Constant.File_TestData, "Sheet1");
////Get the Desired Capabilities
driver = (AndroidDriver<MobileElement>) objAndroidAppSetup.setupCapabilities();
System.out.println("driver2 =" + driver);
Thread.sleep(2000);
}
#Test
public void loginRegisteredMobile() throws Exception {
//Get the data from excel datasheet
String MobileNumber = ExcelUtils.getCellData(1,0);
System.out.println("driver3= " + driver);
objLogin.MobileNumberOnLogin().clear();
//Enter Mobile number
objLogin.MobileNumberOnLogin().sendKeys(MobileNumber);
//Click on Next button
objLogin.NextButtonOnLogin().click();
}
My another Package has below code
package utilities;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.MobileCapabilityType;
import java.net.URL;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import utilities.Constant;
import utilities.ExcelUtils;
public class AndroidAppSetup {
public AndroidDriver<MobileElement> driver;
public AndroidDriver<MobileElement> setupCapabilities() throws Exception{
ExcelUtils.setExcelFileSheet(Constant.Path_TestData+Constant.File_TestData, "Sheet1");
//Get data from excelsheet
String DeviceName = ExcelUtils.getCellData(1,6);
String DeviceId = ExcelUtils.getCellData(1,7);
String AndroidVersion = ExcelUtils.getCellData(1,8);
String AppPackage = Constant.AppPackage;
String AppActivity = Constant.AppActivity;
String AppiumURL = Constant.AppiumURL;
//Set the Desired Capabilities
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("deviceName", DeviceName);
caps.setCapability("udid", DeviceId); //Give Device ID of your mobile phone
caps.setCapability("platformName", "Android");
caps.setCapability("platformVersion", AndroidVersion);
caps.setCapability("appPackage", AppPackage);
caps.setCapability("appActivity", AppActivity);
caps.setCapability(CapabilityType.TAKES_SCREENSHOT, "true");
driver = new AndroidDriver<MobileElement>( new URL(AppiumURL), caps);
System.out.println("driver1= " + driver);
return driver;
}
}
pageObjects.DearoLoginPage is defined in below class
package pageObjects;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
public class DearoLoginPage {
private static MobileElement element = null;
//private AppiumDriver<MobileElement> driver;
private AndroidDriver<MobileElement> driver;
public DearoLoginPage(AndroidDriver<MobileElement> driver) {
// private AndroidDriver<MobileElement> driver;
this.driver = driver;
}
public MobileElement MobileNumberOnLogin(){
System.out.println("driver4 = " + driver);
element = driver.findElement(By.id("com.carworkz.debug:id/et_login_mobile_no"));
return element;
}
When I execute my script I am getting Null pointer exception as below,
INFO: Detected dialect: OSS
driver1= Android: null
driver2 =Android: null
driver=Android: null
driver4 = null
FAILED: loginRegisteredMobile
java.lang.NullPointerException
at pageObjects.DearoLoginPage.MobileNumberOnLogin(DearoLoginPage.java:26)
at testCases.Main_TestCase.loginRegisteredMobile(Main_TestCase.java:148)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:108)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:669)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:877)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1201)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:776)
at org.testng.TestRunner.run(TestRunner.java:634)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:425)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:420)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:385)
at org.testng.SuiteRunner.run(SuiteRunner.java:334)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1318)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1243)
at org.testng.TestNG.runSuites(TestNG.java:1161)
at org.testng.TestNG.run(TestNG.java:1129)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)
Please help me to resolve this issue.

DearoLoginPage class instance object is created and initialized before the driver initialization . Please change the initialization as below and then check.
Modified Main_TestCase Class:
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
import org.testng.Assert;
import io.appium.java_client.MobileElement;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import utilities.Constant;
import utilities.ExcelUtils;
import pageObjects.DearoLoginPage;
import pageObjects.JobCardsPage;
import TestData.MongoDBConnector;
import utilities.AndroidAppSetup;
public class Main_TestCase {
AndroidDriver<MobileElement> driver;
//removed the initialization part and initialization will happen in BeforeClass Method
DearoLoginPage objLogin;
MongoDBConnector objDB = new MongoDBConnector();
AndroidAppSetup objAndroidAppSetup = new AndroidAppSetup();
#BeforeClass
public void setUp() throws Exception{
//This is to open the Excel file. Excel path, file name and the sheet name are parameters to this method
ExcelUtils.setExcelFileSheet(Constant.Path_TestData+Constant.File_TestData, "Sheet1");
////Get the Desired Capabilities
driver = (AndroidDriver<MobileElement>) objAndroidAppSetup.setupCapabilities();
//DearoLoginPage object initialization is added
objLogin= new DearoLoginPage(driver);
System.out.println("driver2 =" + driver);
Thread.sleep(2000);
}
#Test
public void loginRegisteredMobile() throws Exception {
//Get the data from excel datasheet
String MobileNumber = ExcelUtils.getCellData(1,0);
System.out.println("driver3= " + driver);
objLogin.MobileNumberOnLogin().clear();
//Enter Mobile number
objLogin.MobileNumberOnLogin().sendKeys(MobileNumber);
//Click on Next button
objLogin.NextButtonOnLogin().click();
}

Related

Appium Automation - Method has not yet been implemented

I'm trying to explore Mobile App Automation, i'm running into this issue.
package sample;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.android.AndroidDriver;
public class AndroidTest {
static WebDriver driver;
public static void main(String[] args) throws MalformedURLException, InterruptedException
{
File app= new File("C:\\Users\\ASSOUND\\Downloads\\DevOps\\mymbfs60_simulator_0301.apk");
DesiredCapabilities capabilities= new DesiredCapabilities();
capabilities.setCapability("deviceName", "Android Emulator");
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("app", app.getAbsolutePath());
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
driver.findElement(By.id("com.android.packageinstaller:id/permission_allow_button")).click();
driver.quit();
}
}
This code Installs & Launches the App, but when i try to locate the Element and click, i'm getting this error:
Exception in Thread "main" org.openga.selenium.WebDriverException: Method has not yet been implemented (WARNING: The server did not Provide..
Note: i tried to include enough time-wait before locating the element, but its still the same.

unknown error: Unsupported locator strategy: -android uiautomator

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 am unable findthe app_package and app_activity in MobileCompatibityType while coding in eclipse for appium.This is for testing the native app

import java.net.URL;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.BeforeClass;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.MobileCapabilityType;
public class LaunchAppium {
AndroidDriver driver;
// driver = new AndroidDriver("http://127.0.0.1:4723/wd/hub", test);
#BeforeClass
public void setup() throws MalformedURLException
{
DesiredCapabilities test=new DesiredCapabilities();
test.setCapability(MobileCapabilityType.DEVICE_NAME, "Androidemulator");
test.setCapability(MobileCapabilityType.APP, "Ebutor 15_dec_2016.apk");
//test.setCapability(MobileCapabilityType., value);
driver = new AndroidDr`enter code here`iver(new URL("http://127.0.0.1:4723/wd/hub"), test);
}
In the above pice of code i could not find the APP_PACKAGE and APP_ACTIVITY for the mobilecapabilitytpe instance which is essential for the android settings.
PLEASE HELP!!!
From 4.0, this is moved to specific to android package:
public interface AndroidMobileCapabilityType extends CapabilityType {
/**
* Activity name for the Android activity you want to launch from your package.
* This often needs to be preceded by a . (e.g., .MainActivity instead of MainActivity).
*/
String APP_ACTIVITY = "appActivity";
/**
* Java package of the Android app you want to run.
*/
String APP_PACKAGE = "appPackage";
/**
* Activity name for the Android activity you want to wait for.
*/
String APP_WAIT_ACTIVITY = "appWaitActivity";
}
So you have to use
AndroidMobileCapabilityType.APP_ACTIVITY
Please check the above it should work or you can see the see # link
package com.appium.android;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.By;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.MobileCapabilityType;
public class LaunchAppium {
static AndroidDriver driver;
// driver = new AndroidDriver("http://127.0.0.1:4723/wd/hub", test);
#SuppressWarnings("deprecation")
#BeforeClass
public void setup() throws MalformedURLException
{
DesiredCapabilities test=new DesiredCapabilities();
//test.setCapability(MobileCapabilityType.APP_PACKAGE, "com.veronicaapps.veronica.simplecalculator");
//test.setCapability(MobileCapabilityType.APP_ACTIVITY, "com.veronicaapps.veronica.simplecalculator.MainActivity");
test.setCapability(MobileCapabilityType.DEVICE_NAME, "emulator");
test.setCapability(MobileCapabilityType.VERSION, "4.2.2");
test.setCapability(MobileCapabilityType.PLATFORM_NAME, "android");
//test.setCapability("appPackage",
"com.veronicaapps.veronica.simplecalculator");
//test.setCapability("appActivity", ".MainActivity");
//driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),
test);
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), test);
}
public interface AndroidMobileCapabilityType extends CapabilityType {
String APP_ACTIVITY = "com.veronicaapps.veronica.simplecalculator.MainActivity";
String APP_PACKAGE = "com.veronicaapps.veronica.simplecalculator";
}
#Test
public void atest() throws Exception
{
WebDriver two=(WebDriver) driver.findElement(By.linkText("2"));
((WebElement) two).click();
WebDriver plus= (WebDriver) driver.findElement(By.linkText("+"));
((WebElement) plus).click();
WebDriver five= (WebDriver) driver.findElement(By.linkText("5"));
((WebElement) five).click();
WebDriver equal= (WebDriver) driver.findElement(By.linkText("="));
((WebElement) equal).click();
}
}

Appium: Why am I seeing a desiredcapabilties error in the log even after I have provided all the relevant values?

I ran the following code for Automating a simple Test for Android via Appium:
package appiumtest;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.*;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.AppiumSetting;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.*;
import org.testng.*;
//import org.junit.*;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.*;
public class AppiumTest {
public static void main(String[] args) throws InterruptedException, MalformedURLException{
// TODO Auto-generated method stub
AppiumTest testcases = new AppiumTest();
testcases.launchtest();
}
public void launchtest() throws InterruptedException, MalformedURLException{
File app = new File("D:\\Radio\\ebayTest.apk");
DesiredCapabilities capabilities = new DesiredCapabilities();
AndroidDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
capabilities.setCapability(CapabilityType.BROWSER_NAME,"");
capabilities.setCapability("platformname", "Android");
capabilities.setCapability(CapabilityType.VERSION,"4.4.2");
capabilities.setCapability("deviceName", "07d4bb0a00caa300");
capabilities.setCapability("app", app.getAbsolutePath());
capabilities.setCapability("appPackage", "com.ebay.mobile");
capabilities.setCapability("appActivity", ".activities.eBay");
Thread.sleep(3000);
System.out.println("App launched");
WebElement signin = driver.findElement(By.id("button_sign_in"));
signin.click();
Thread.sleep(4000);
}
}
Now after running the test, I continuously see the error message shown below in the logs and the Appium Server Window:
Exception in thread "main" org.openqa.selenium.SessionNotCreatedException: A new session could not be created. (Original error: The following desired capabilities are required, but were not provided: deviceName) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 200 milliseconds
Why am I seeing this error message? I have provided the correct device name parameter in Desired Capabilities as seen in 'adb devices'.
You initialized the driver with the capabilities before all the capabilities were set.
Move this line AndroidDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
after this line capabilities.setCapability("appActivity", ".activities.eBay");

PKCS10CertificationRequestBuilder generates invalid PKCS10CertificationRequest in org.bouncycastle.pkcs

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

Categories

Resources