634 lines
19 KiB
Java
634 lines
19 KiB
Java
/* WolfSSLX509Name.java
|
|
*
|
|
* Copyright (C) 2006-2025 wolfSSL Inc.
|
|
*
|
|
* This file is part of wolfSSL.
|
|
*
|
|
* wolfSSL is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* wolfSSL is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
|
*/
|
|
package com.wolfssl;
|
|
|
|
/**
|
|
* WolfSSLX509Name class, wraps native WOLFSSL_X509_NAME functionality.
|
|
*/
|
|
public class WolfSSLX509Name {
|
|
|
|
private boolean active = false;
|
|
private long x509NamePtr = 0;
|
|
|
|
/* Lock around active state */
|
|
private final Object stateLock = new Object();
|
|
|
|
/* Lock around x509NamePtr pointer access */
|
|
private final Object x509NameLock = new Object();
|
|
|
|
/* Cache name elements in Java before pushing through JNI, for easier
|
|
* retrieval from getXXX() methods */
|
|
private String countryName = null;
|
|
private String stateOrProvinceName = null;
|
|
private String streetAddress = null;
|
|
private String localityName = null;
|
|
private String surname = null;
|
|
private String commonName = null;
|
|
private String emailAddress = null;
|
|
private String organizationName = null;
|
|
private String organizationalUnitName = null;
|
|
private String postalCode = null;
|
|
private String userId = null;
|
|
|
|
/* Encoding types, matched to native define values */
|
|
private static final int MBSTRING_UTF8 = 0x100;
|
|
|
|
/* Native JNI methods */
|
|
static native long X509_NAME_new();
|
|
static native void X509_NAME_free(long x509Name);
|
|
static native int X509_NAME_add_entry_by_txt(long x509Name, String field,
|
|
int type, byte[] entry, int len, int loc, int set);
|
|
|
|
/**
|
|
* Create new empty WolfSSLX509Name object.
|
|
*
|
|
* @throws WolfSSLException if native API call fails.
|
|
*/
|
|
public WolfSSLX509Name() throws WolfSSLException {
|
|
|
|
x509NamePtr = X509_NAME_new();
|
|
if (x509NamePtr == 0) {
|
|
throw new WolfSSLException("Failed to create WolfSSLX509Name");
|
|
}
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, x509NamePtr,
|
|
() -> "creating new WolfSSLX509Name");
|
|
|
|
synchronized (stateLock) {
|
|
this.active = true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Verifies that the current WolfSSLX509Name object is active.
|
|
*
|
|
* @throws IllegalStateException if object has been freed
|
|
*/
|
|
private void confirmObjectIsActive()
|
|
throws IllegalStateException {
|
|
|
|
synchronized (stateLock) {
|
|
if (this.active == false) {
|
|
throw new IllegalStateException(
|
|
"WolfSSLX509Name object has been freed");
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* For package use only, return native WOLFSSL_X509_NAME pointer.
|
|
*
|
|
* @return native WOLFSSL_X509_POINTER value
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
*/
|
|
protected long getNativeX509NamePtr() throws IllegalStateException {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
/* TODO lock around x509NamePtr for caller use */
|
|
synchronized (x509NameLock) {
|
|
return this.x509NamePtr;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Private helper function to call native JNI function
|
|
* X509_NAME_add_entry_by_txt().
|
|
*
|
|
* @param field String containing field name to set, for example
|
|
* "countryName"
|
|
* @param entry String value to store into field
|
|
*
|
|
* @throws WolfSSLException if arguments are invalid or error occurs
|
|
* with native JNI call.
|
|
*/
|
|
private synchronized void addEntryByTxt(String field, String entry)
|
|
throws WolfSSLException {
|
|
|
|
int ret = 0;
|
|
|
|
if (field == null || entry == null) {
|
|
throw new WolfSSLException(
|
|
"field or entry is null in addEntryByTxt()");
|
|
}
|
|
|
|
synchronized (x509NameLock) {
|
|
ret = X509_NAME_add_entry_by_txt(this.x509NamePtr, field,
|
|
MBSTRING_UTF8, entry.getBytes(),
|
|
entry.getBytes().length, -1, 0);
|
|
}
|
|
|
|
if (ret != WolfSSL.SSL_SUCCESS) {
|
|
throw new WolfSSLException("Error setting " + field +
|
|
" into WolfSSLX509Name (error: " + ret + ")");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set country name for this name object.
|
|
*
|
|
* @param countryName String containing country name to be set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
* @throws WolfSSLException if native JNI error has occurred, or input
|
|
* argument is invalid.
|
|
*/
|
|
public synchronized void setCountryName(String countryName)
|
|
throws IllegalStateException, WolfSSLException {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered setCountryName(" + countryName + ")");
|
|
|
|
addEntryByTxt("countryName", countryName);
|
|
this.countryName = countryName;
|
|
}
|
|
|
|
/**
|
|
* Set state or province name for this name object.
|
|
*
|
|
* @param name String containing state or province name to be set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
* @throws WolfSSLException if native JNI error has occurred, or input
|
|
* argument is invalid.
|
|
*/
|
|
public synchronized void setStateOrProvinceName(String name)
|
|
throws IllegalStateException, WolfSSLException {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered setStateOrProvinceName(" + name + ")");
|
|
|
|
addEntryByTxt("stateOrProvinceName", name);
|
|
this.stateOrProvinceName = name;
|
|
}
|
|
|
|
/**
|
|
* Set street address for this name object.
|
|
*
|
|
* @param address String containing street address to be set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
* @throws WolfSSLException if native JNI error has occurred, or input
|
|
* argument is invalid.
|
|
*/
|
|
public synchronized void setStreetAddress(String address)
|
|
throws IllegalStateException, WolfSSLException {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered setStreetAddress(" + address + ")");
|
|
|
|
addEntryByTxt("streetAddress", address);
|
|
this.streetAddress = address;
|
|
}
|
|
|
|
/**
|
|
* Set locality name / city for this name object.
|
|
*
|
|
* @param name String containing locality name to be set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
* @throws WolfSSLException if native JNI error has occurred, or input
|
|
* argument is invalid.
|
|
*/
|
|
public synchronized void setLocalityName(String name)
|
|
throws IllegalStateException, WolfSSLException {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered setLocalityName(" + name + ")");
|
|
|
|
addEntryByTxt("localityName", name);
|
|
this.localityName = name;
|
|
}
|
|
|
|
/**
|
|
* Set surname for this name object.
|
|
*
|
|
* @param name String containing surname to be set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
* @throws WolfSSLException if native JNI error has occurred, or input
|
|
* argument is invalid.
|
|
*/
|
|
public synchronized void setSurname(String name)
|
|
throws IllegalStateException, WolfSSLException {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered setSurname(" + name + ")");
|
|
|
|
addEntryByTxt("surname", name);
|
|
this.surname = name;
|
|
}
|
|
|
|
/**
|
|
* Set common name for this name object.
|
|
*
|
|
* @param name String containing common name to be set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
* @throws WolfSSLException if native JNI error has occurred, or input
|
|
* argument is invalid.
|
|
*/
|
|
public synchronized void setCommonName(String name)
|
|
throws IllegalStateException, WolfSSLException {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered setCommonName(" + name + ")");
|
|
|
|
addEntryByTxt("commonName", name);
|
|
this.commonName = name;
|
|
}
|
|
|
|
/**
|
|
* Set email address for this name object.
|
|
*
|
|
* @param email String containing email address to be set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
* @throws WolfSSLException if native JNI error has occurred, or input
|
|
* argument is invalid.
|
|
*/
|
|
public synchronized void setEmailAddress(String email)
|
|
throws IllegalStateException, WolfSSLException {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered setEmailAddress(" + email + ")");
|
|
|
|
addEntryByTxt("emailAddress", email);
|
|
this.emailAddress = email;
|
|
}
|
|
|
|
/**
|
|
* Set organization name for this name object.
|
|
*
|
|
* @param name String containing organization name to be set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
* @throws WolfSSLException if native JNI error has occurred, or input
|
|
* argument is invalid.
|
|
*/
|
|
public synchronized void setOrganizationName(String name)
|
|
throws IllegalStateException, WolfSSLException {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered setOrganizationName(" + name + ")");
|
|
|
|
addEntryByTxt("organizationName", name);
|
|
this.organizationName = name;
|
|
}
|
|
|
|
/**
|
|
* Set organizational unit name for this name object.
|
|
*
|
|
* @param name String containing organizational unit name to be set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
* @throws WolfSSLException if native JNI error has occurred, or input
|
|
* argument is invalid.
|
|
*/
|
|
public synchronized void setOrganizationalUnitName(String name)
|
|
throws IllegalStateException, WolfSSLException {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered setOrganizationalUnitName(" + name + ")");
|
|
|
|
addEntryByTxt("organizationalUnitName", name);
|
|
this.organizationalUnitName = name;
|
|
}
|
|
|
|
/**
|
|
* Set postal code for this name object.
|
|
*
|
|
* @param code String containing postal code to be set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
* @throws WolfSSLException if native JNI error has occurred, or input
|
|
* argument is invalid.
|
|
*/
|
|
public synchronized void setPostalCode(String code)
|
|
throws IllegalStateException, WolfSSLException {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered setPostalCode(" + code + ")");
|
|
|
|
addEntryByTxt("postalCode", code);
|
|
this.postalCode = code;
|
|
}
|
|
|
|
/**
|
|
* Set user ID for this name object.
|
|
*
|
|
* @param id String containing user ID to be set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
* @throws WolfSSLException if native JNI error has occurred, or input
|
|
* argument is invalid.
|
|
*/
|
|
public synchronized void setUserId(String id)
|
|
throws IllegalStateException, WolfSSLException {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered setUserId(" + id + ")");
|
|
|
|
addEntryByTxt("userId", id);
|
|
this.userId = id;
|
|
}
|
|
|
|
/**
|
|
* Get country name set in this object.
|
|
*
|
|
* @return country name string, or null if not yet set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
*/
|
|
public synchronized String getCountryName() {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered getCountryName()");
|
|
|
|
return this.countryName;
|
|
}
|
|
|
|
/**
|
|
* Get state or province name set in this object.
|
|
*
|
|
* @return state or province name string, or null if not yet set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
*/
|
|
public synchronized String getStateOrProvinceName() {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered getStateOrProvinceName()");
|
|
|
|
return this.stateOrProvinceName;
|
|
}
|
|
|
|
/**
|
|
* Get street address set in this object.
|
|
*
|
|
* @return street address string, or null if not yet set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
*/
|
|
public synchronized String getStreetAddress() {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered getStreetAddress()");
|
|
|
|
return this.streetAddress;
|
|
}
|
|
|
|
/**
|
|
* Get locality name set in this object.
|
|
*
|
|
* @return locality name string, or null if not yet set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
*/
|
|
public synchronized String getLocalityName() {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered getLocalityName()");
|
|
|
|
return this.localityName;
|
|
}
|
|
|
|
/**
|
|
* Get surname set in this object.
|
|
*
|
|
* @return surname string, or null if not yet set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
*/
|
|
public synchronized String getSurname() {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered getSurname()");
|
|
|
|
return this.surname;
|
|
}
|
|
|
|
/**
|
|
* Get common name set in this object.
|
|
*
|
|
* @return common name string, or null if not yet set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
*/
|
|
public synchronized String getCommonName() {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered getCommonName()");
|
|
|
|
return this.commonName;
|
|
}
|
|
|
|
/**
|
|
* Get email address set in this object.
|
|
*
|
|
* @return email address string, or null if not yet set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
*/
|
|
public synchronized String getEmailAddress() {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered getEmailAddress()");
|
|
|
|
return this.emailAddress;
|
|
}
|
|
|
|
/**
|
|
* Get organization name set in this object.
|
|
*
|
|
* @return organization name string, or null if not yet set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
*/
|
|
public synchronized String getOrganizationName() {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered getOrganizationName()");
|
|
|
|
return this.organizationName;
|
|
}
|
|
|
|
/**
|
|
* Get organizational unit name set in this object.
|
|
*
|
|
* @return organizational unit name string, or null if not yet set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
*/
|
|
public synchronized String getOrganizationalUnitName() {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered getOrganizationalUnitName()");
|
|
|
|
return this.organizationalUnitName;
|
|
}
|
|
|
|
/**
|
|
* Get postal code set in this object.
|
|
*
|
|
* @return postal code string, or null if not yet set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
*/
|
|
public synchronized String getPostalCode() {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered getPostalCode()");
|
|
|
|
return this.postalCode;
|
|
}
|
|
|
|
/**
|
|
* Get user ID set in this object.
|
|
*
|
|
* @return user ID string, or null if not yet set
|
|
*
|
|
* @throws IllegalStateException if WolfSSLX509Name has been freed.
|
|
*/
|
|
public synchronized String getUserId() {
|
|
|
|
confirmObjectIsActive();
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered getUserId()");
|
|
|
|
return this.userId;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
|
|
synchronized (stateLock) {
|
|
if (this.active == false) {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
/* TODO: wrap wolfSSL_X509_NAME_oneline() */
|
|
return "";
|
|
}
|
|
|
|
/**
|
|
* Free native resources of WolfSSLX509Name.
|
|
*/
|
|
public synchronized void free() {
|
|
|
|
synchronized (stateLock) {
|
|
if (this.active == false) {
|
|
/* already freed, just return */
|
|
return;
|
|
}
|
|
|
|
synchronized (x509NameLock) {
|
|
|
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
|
WolfSSLDebug.INFO, this.x509NamePtr,
|
|
() -> "entered free()");
|
|
|
|
/* free native resources */
|
|
X509_NAME_free(this.x509NamePtr);
|
|
|
|
this.active = false;
|
|
this.x509NamePtr = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
@SuppressWarnings("deprecation")
|
|
@Override
|
|
protected void finalize() throws Throwable
|
|
{
|
|
this.free();
|
|
super.finalize();
|
|
}
|
|
}
|
|
|