Error while execute java procedure from Oracle Database - java

I have java code to read certificate from USB token. The code is working properly as stand alone Java class.
After importing Java class into Oracle Database (19c), with loadjava utility, the Java class is imported successfully but after execution it gives the below error:
java.security.KeyStoreException: PKCS11 not found
The above error means the security provider not added. In the stand alone Java class, to fix this error, just add the following line to java.security file in Java directory:
security.provider.13=SunPKCS11 configration_file.cfg
I also added the above line to java.security, in javavm folder, in the database home but that didn't fix the error.
The used Java code is:
class GetSignatureNew {
public static void main(String args[])
{
GetSignatureNew sdk = new GetSignatureNew();
}
public static String GetSignatureFun(String serialized)
{
String pwd = "*******";
char[] pin = new char[pwd.length()];
try
{
for (int i = 0; i < pwd.length(); i++) {
pin[i] = pwd.charAt(i);
}
// Get Certificate and private key from token
KeyStore ks = KeyStore.getInstance("PKCS11");
ks.load(null, pin);
Enumeration enu = ks.aliases();
String alias = String.valueOf(enu.nextElement());
X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
PrivateKey pk = (PrivateKey) ks.getKey(alias, pin);
byte [] output = cert.getEncoded();
String b64 = Base64.getEncoder().encodeToString(output);
return b64;
}
catch (Exception e) {
e.printStackTrace();
return e.toString();
}
}
}
Anybody has an idea.
Thanks in advance.
Execute Java Procedure
the output is not correct because it gives
"java.security.KeyStoreException: PKCS11 not found"

As a workaround, I tried to create a schedule job on oracle to run batch and this batch will run java code.
Unfortunately, when i run the batch the batch is run successfully but if i run the oracle job it run with error also
STANDARD_ERROR="java.security.KeyStoreException: PKCS11 not found
at java.base/java.security.KeyStore.getInstance(KeyStore.java:878)
at GetSignatureDB.main(GetSignatureDB.java:102)
Caused by: java.security.NoSuc"
Schedule Job
BEGIN
SYS.DBMS_SCHEDULER.CREATE_JOB( job_name => 'einvoice_signature_job',
job_type => 'EXECUTABLE',
job_action => 'C:\WINDOWS\system32\cmd.exe',
job_class => 'DEFAULT_JOB_CLASS',
comments => 'Job to call batch script on Windows',
auto_drop => FALSE,
number_of_arguments => 3,
enabled => FALSE);
SYS.DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( job_name => 'einvoice_signature_job', argument_position => 1, argument_value => '/q');
SYS.DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( job_name => 'einvoice_signature_job', argument_position => 2, argument_value => '/c');
SYS.DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( job_name => 'einvoice_signature_job', argument_position => 3, argument_value => '"E:\Backup\eInvoice\GetCert.bat"');
SYS.DBMS_SCHEDULER.ENABLE( 'einvoice_signature_job' );
END;
/
batch file
cd E:\Backup\eInvoice
E:
"C:\Program Files\Java\jdk-9.0.1\bin\java" GetSignatureNew
which GetSignatureNew is the java class listed in the original post.
the batch works fine if i run it manually.
but when i run the Oracle job
BEGIN
DBMS_SCHEDULER.RUN_JOB ('einvoice_signature_job');
END;
it runs and return the above error

Related

React jest and MSAL getting BrowserAuthError : crypto

I'm trying to test a few components that are using MSAL for authentication.
Thus far, I have a simple test, which test if my component can render, as follows:
// <MsalInstanceSnippet>
const msalInstance = new PublicClientApplication({
auth: {
clientId: config.appId,
redirectUri: config.redirectUri
},
cache: {
cacheLocation: 'sessionStorage',
storeAuthStateInCookie: true
}
});
When I run the test, I'm getting the following error:
BrowserAuthError: crypto_nonexistent: The crypto object or function is not available. Detail:Browser crypto or msCrypto object not available.
10 |
11 | // <MsalInstanceSnippet>
> 12 | const msalInstance = new PublicClientApplication({
| ^
13 | auth: {
14 | clientId: config.appId,
15 | redirectUri: config.redirectUri
at BrowserAuthError.AuthError [as constructor] (node_modules/#azure/msal-common/dist/error/AuthError.js:27:24)
at new BrowserAuthError (node_modules/#azure/msal-browser/src/error/BrowserAuthError.ts:152:9)
at Function.Object.<anonymous>.BrowserAuthError.createCryptoNotAvailableError (node_modules/#azure/msal-browser/src/error/BrowserAuthError.ts:172:16)
at new BrowserCrypto (node_modules/#azure/msal-browser/src/crypto/BrowserCrypto.ts:31:36)
at new CryptoOps (node_modules/#azure/msal-browser/src/crypto/CryptoOps.ts:45:30)
at PublicClientApplication.ClientApplication (node_modules/#azure/msal-browser/src/app/ClientApplication.ts:108:58)
at new PublicClientApplication (node_modules/#azure/msal-browser/src/app/PublicClientApplication.ts:49:9)
at Object.<anonymous> (src/App.test.tsx:12:22)
I'm unsure what the above means, but as far as I can understand, this error is occurring because the session is not authenticated.
My question can therefore be divided into the following:
What does this error mean?
How can I solve this error? (Can we bypass MSAL by any chance for testing purposes?)
You need to add crypto to your Jest config in jest.config.js:
module.exports = {
// ...
globals: {
// ...
crypto: require("crypto")
}
};
For eslint issue
try this way
import crypto from 'crypto';
module.exports = {
// ...
globals: {
// ...
crypto,
}
};
I tried adding crypto to my jest.config.js, but it didn't work. Then I tried adding it package.json. It was also pointless giving this error.
Out of the box, Create React App only supports overriding these Jest options:
• clearMocks
• collectCoverageFrom
• coveragePathIgnorePatterns
• coverageReporters
• coverageThreshold
• displayName
• extraGlobals
• globalSetup
• globalTeardown
• moduleNameMapper
• resetMocks
• resetModules
• restoreMocks
• snapshotSerializers
• testMatch
• transform
• transformIgnorePatterns
• watchPathIgnorePatterns.
These options in your package.json Jest configuration are not currently supported by Create React App:
In my case, I have a custom hook that has a dependency with msalInstance
I can prevent the above error by mocking my hook as said here
But still, this wasn't a good solution because if I have many hooks like this. So what I did was mock msalInstance in setupTests.ts file
jest.mock('./msal-instance', () => ({
getActiveAccount: () => ({}),
acquireTokenSilent: () => Promise.resolve({ accessToken: '' }),
}));
This is my msal-instance.ts
import {
PublicClientApplication,
EventType,
EventMessage,
AuthenticationResult,
} from '#azure/msal-browser';
import { msalConfig } from './authConfig';
const msalInstance = new PublicClientApplication(msalConfig);
// Account selection logic is app dependent. Adjust as needed for different use cases.
const accounts = msalInstance.getAllAccounts();
if (accounts.length > 0) {
msalInstance.setActiveAccount(accounts[0]);
}
msalInstance.addEventCallback((event: EventMessage) => {
if (event.eventType === EventType.LOGIN_SUCCESS && event.payload) {
const payload = event.payload as AuthenticationResult;
const { account } = payload;
msalInstance.setActiveAccount(account);
}
});
export default msalInstance;
For react version 17.x.x you can install "#wojtekmaj/enzyme-adapter-react-17" package and after that you can create a src/setupTests.js file. You can add all your environment variables and other configurations to this file as follows:
//This is for the issue above
const nodeCrypto = require("crypto");
window.crypto = {
getRandomValues: function (buffer) {
return nodeCrypto.randomFillSync(buffer);
},
};
//It is also possible to add ENV variables
window.ENV = {
ApiURL: {
lessonsUrl: "https://myApiURL.com/APIendpoint",
}
CloudUiUrl: "localhost:3000",
};
When you run your tests #wojtekmaj/enzyme-adapter-react-17 will take the settings in this file automatically.

Error: Could not find or load main class mysql-connector-java-8.0.23.jar : Why?

I'm trying to learn JDBCs. But every time I try running my program I keep getting this error.
Error: Could not find or load main class mysql-connector-java-8.0.23.jar
I've downloaded the MySQL Connector/J and installed the driver by placing MySQL-connector-java-version-bin.jar in the PATH.
The mysql-connector-java-8.0.23.jar file has also been placed in the folder that's got the source code.
Here's my code
import java.sql.* ;
public class Program1
{
public static void main(String[] args)
{
String password = "abc123" ;
try
{
Class.forName("com.mysql.cj.jdbc.Driver").newInstance() ;
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db_test1", "root", password) ;
Statement stmnt = conn.createStatement() ;
ResultSet resultSet = stmnt.executeQuery("SELECT * FROM tblStudents") ;
while(resultSet.next() == true)
{
String stdID = resultSet.getString("StudentID") ;
String stdName = resultSet.getString("Name") ;
System.out.println(stdID + " | " + stdName);
}
}
catch(Exception e)
{
System.out.println("Exceptions -> \n" + e + "\n") ;
}
}
}
I compiled and ran the program in the terminal using java -cp .; mysql-connector-java-8.0.23.jar Program1.
The first few times I ran the program, it worked. And now it doesn't.
Bad java calling syntax.
What you probably wanted to do was:
java -cp ./mysql-connector-java-8.0.23.jar Program1.
The line you have above is effectively treating your mysql.jar as the JAR having the class to load and NOT as the library it needs (which is what you wanted)

Alloy api solution set

I have this simple model written in Alloy:
module login
sig Email {}
sig Password {}
sig User {
login: one Login
}
sig Login {
email: one Email,
password: one Password,
owner: one User,
}
fact {
all u:User | u.login.owner = u
}
assert a {
all l:Login | one l.owner
all u:User | one u.login.email
all u:User | u.login.owner = u
}
check a for 3
If I run this with the alloy analyser GUI it says:
No counterexample found. Assertion may be valid. 11ms.
But if I run the same model with the API in my java program it returns:
---OUTCOME---
Unsatisfiable.
And not even 1 solutions is shown.
Can anyone help me to detect the problem?
Here goes the code in java using the API:
A4Reporter rep = new A4Reporter();
try {
Module loaded_model = CompUtil.parseEverything_fromFile(rep, null, model.getModelpath());
A4Options options = new A4Options();
options.solver = A4Options.SatSolver.SAT4J;
Command cmd = loaded_model.getAllCommands().get(0);
A4Solution sol = TranslateAlloyToKodkod.execute_command(rep, loaded_model.getAllReachableSigs(), cmd, options);
System.out.println(sol.toString());
while (sol.satisfiable()) {
System.out.println("[Solution]:");
System.out.println(sol.toString());
sol = sol.next();
}
} catch (Err e){
e.printStackTrace();
}
Thanks
In both cases no counter-examples are found.
Be aware that the command obtained via the method call loaded_model.getAllCommands().get(0) is check a for 3 in other words, you ask Alloy to look for counter examples.
If you would like to obtain an instance satisfying your constraints - i.e., not a counter-example - you should use a command containing the keyword run instead of check.

Undefined CommonName in certificate

So far, I've been working with a certificate which I added to a SoapUI 5.2 project and which gave me access to a pre-production server. However, now that I'm ready to move to a production environment, I'm trying to check the new production certificate with SoapUI, but I'm getting the next error:
WARN:Using fallback method to load keystore/truststore due to: Invalid keystore format
ERROR:An error occurred [java.lang.NullPointerException], see error log for details
And the error log says:
ERROR:Could not load keystore/truststore
ERROR:java.lang.NullPointerException
java.lang.NullPointerException
at org.apache.commons.ssl.KeyStoreBuilder.build(KeyStoreBuilder.java:176)
at org.apache.commons.ssl.KeyStoreBuilder.build(KeyStoreBuilder.java:97)
at org.apache.commons.ssl.KeyStoreBuilder.build(KeyStoreBuilder.java:88)
at com.eviware.soapui.impl.wsdl.support.wss.crypto.KeyMaterialWssCrypto.fallbackLoad(KeyMaterialWssCrypto.java:206)
at com.eviware.soapui.impl.wsdl.support.wss.crypto.KeyMaterialWssCrypto.load(KeyMaterialWssCrypto.java:168)
at com.eviware.soapui.impl.wsdl.support.wss.crypto.KeyMaterialWssCrypto.getStatus(KeyMaterialWssCrypto.java:216)
at com.eviware.soapui.impl.wsdl.panels.project.WSSTabPanel$CryptoTableModel.getValueAt(WSSTabPanel.java:643)
at javax.swing.JTable.getValueAt(Unknown Source)
at javax.swing.JTable.prepareRenderer(Unknown Source)
...
The only difference I found between the pre-production and production certificates was that the latter did not have the CommonName field defined.
I know that field is not mandatory, so how is that possible? How can I solve this problem without asking for a new certificate? That's not an option.
Any suggestion would be appreciated.
I check the pom.xml of SOAPUI project for 5.2 versión, and it use not-yet-commons-ssl versión 0.3.11:
<dependency>
<groupId>commons-ssl</groupId>
<artifactId>not-yet-commons-ssl</artifactId>
<version>0.3.11</version>
</dependency>
And If you check the build method for org.apache.commons.ssl.KeyStoreBuilder class as the exception thrown in your error log you'll see:
public static KeyStore build(byte[] jksOrCerts, byte[] privateKey,
char[] jksPassword, char[] keyPassword)
throws IOException, CertificateException, KeyStoreException,
NoSuchAlgorithmException, InvalidKeyException,
NoSuchProviderException, ProbablyBadPasswordException,
UnrecoverableKeyException {
...
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, jksPassword);
Iterator keysIt = keys.iterator();
Iterator chainsIt = chains.iterator();
int i = 1;
while (keysIt.hasNext() && chainsIt.hasNext()) {
Key key = (Key) keysIt.next();
Certificate[] c = (Certificate[]) chainsIt.next();
X509Certificate theOne = buildChain(key, c);
String alias = "alias_" + i++;
// The theOne is not null, then our chain was probably altered.
// Need to trim out the newly introduced null entries at the end of
// our chain.
if (theOne != null) {
c = Certificates.trimChain(c);
alias = Certificates.getCN(theOne);
/* line 176 */ alias = alias.replace(' ', '_');
}
ks.setKeyEntry(alias, key, keyPassword, c);
}
return ks;
}
}
So seems that you're right and the problem is that your certificate has no common name, so org.apache.commons.ssl.Certificates.getCN(X509Certificate) returns null as alias and then alias.replace is throwing the NPE.
alias = Certificates.getCN(theOne);
/* line 176 */ alias = alias.replace(' ', '_');
I don't see nothing that says that Common Name is mandatory in RFC5280, however various code/software use it for different purposes as not-yet-commons-ssl does.
Your certificate is probably right but you can't use it with SOAPUI 5.2 version to test your environment if it hasn't the CN, so if you want to use SOAPUI to test your environment I think that you've to reissue the certificate generating a CSR with CN. Or you can report the problem to http://juliusdavies.ca/commons-ssl/ and then ask to SOAPUI to include the latest version...
Hope this helps,

Can you extract a pl/java class file from an Oracle Database?

I have a pl/java class in a running Oracle database that I have misplaced the source code to.
Is there anyway to get the java bytecode back out the database so I could run it against a decompiler?
I've already checked ALL_SOURCE and Oracle claims it doesn't have the source code.
I had to do this myself recently, and put together a Groovy script to do it. You need to modify the connection details and make sure you've got Oracle database drivers on your classpath
import groovy.sql.Sql
// Change the following to your requirements ...
def extractRoot = "extracted-classes/" // Directory to extract classes into
def user = 'SCOTT' // Schema user
def password = 'tiger' // Yes, it's the password
def host = 'localhost' // Database host
def sid = 'orcl' // Database SID
def port = 1521 // Database listener port
def saveBlob(blob, root, name, extension) {
def byteStream = blob.getBinaryStream()
def bytes = new byte[blob.length()]
byteStream.read(bytes)
def dir = root + name.replaceAll(/\/[^\/]+$/, '')
if (dir != name) {
new File(dir).mkdirs()
}
def f = new File(root + name + extension)
println "Writing ${f.getCanonicalPath()}"
f.delete()
f.withOutputStream { s ->
s.write(bytes)
}
}
sql = Sql.newInstance("jdbc:oracle:thin:#${host}:${port}:${sid}", user,
password, 'oracle.jdbc.driver.OracleDriver')
sql.eachRow("select name from all_java_classes where owner = ${user}") {
sql.call('''
declare
b blob;
begin
dbms_lob.createtemporary(b, FALSE);
dbms_java.export_class(?, ?, b);
? := b;
end;''', [it.name, user, Sql.BLOB]) { blob ->
saveBlob(blob, extractRoot, it.name, '.class')
}
}
sql.eachRow("select dbms_java.longname(object_name) \"name\" from all_objects where object_type = \'JAVA RESOURCE\' and owner = ${user}") {
sql.call('''
declare
b blob;
begin
dbms_lob.createtemporary(b, FALSE);
dbms_java.export_resource(?, ?, b);
? := b;
end;''', [it.name, user, Sql.BLOB]) { blob ->
saveBlob(blob, extractRoot, it.name, '')
}
}
If you know some information about it then you can use dbms_java.
Specifically, judging by your question, export_class; though this may require more detective work on your part. If your code is stored in a actual package, dbms_metadata should be able to help as well.
Java objects should also show up in all_objects, which'll help you track down the schema and/or name if needs be.

Categories