use of com.unboundid.asn1.ASN1BitString in project LinLong-Java by zhenwei1108.
the class X509CertificateImpl method getIssuerUniqueID.
public boolean[] getIssuerUniqueID() {
ASN1BitString id = c.getTBSCertificate().getIssuerUniqueId();
if (id != null) {
byte[] bytes = id.getBytes();
boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
for (int i = 0; i != boolId.length; i++) {
boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
}
return boolId;
}
return null;
}
use of com.unboundid.asn1.ASN1BitString in project LinLong-Java by zhenwei1108.
the class X509CertificateImpl method getSubjectUniqueID.
public boolean[] getSubjectUniqueID() {
ASN1BitString id = c.getTBSCertificate().getSubjectUniqueId();
if (id != null) {
byte[] bytes = id.getBytes();
boolean[] boolId = new boolean[bytes.length * 8 - id.getPadBits()];
for (int i = 0; i != boolId.length; i++) {
boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
}
return boolId;
}
return null;
}
use of com.unboundid.asn1.ASN1BitString in project openkeystore by cyberphone.
the class CA method createCert.
public X509Certificate createCert(CertSpec certSpec, DistinguishedName issuerName, BigInteger serialNumber, Date startDate, Date endDate, AsymKeySignerInterface signer, PublicKey issuerPublicKey, PublicKey subjectPublicKey) throws IOException, GeneralSecurityException {
Extensions extensions = new Extensions();
BaseASN1Object version = new CompositeContextSpecific(0, new ASN1Integer(2));
DistinguishedName subjectName = certSpec.getSubjectDistinguishedName();
BaseASN1Object validity = new ASN1Sequence(new BaseASN1Object[] { getASN1Time(startDate), getASN1Time(endDate) });
AsymSignatureAlgorithms certSignAlg = signer.getAlgorithm();
BaseASN1Object signatureAlgorithm = new ASN1Sequence(certSignAlg.getKeyType() == KeyTypes.RSA ? new BaseASN1Object[] { new ASN1ObjectID(certSignAlg.getOid()), // Relic from the RSA hey-days...
new ASN1Null() } : new BaseASN1Object[] { new ASN1ObjectID(certSignAlg.getOid()) });
BaseASN1Object subjectPublicKeyInfo = DerDecoder.decode(subjectPublicKey.getEncoded());
// ////////////////////////////////////////////////////
if (certSpec.endEntity) {
extensions.add(CertificateExtensions.BASIC_CONSTRAINTS, false, new ASN1Sequence(new BaseASN1Object[] {}));
}
// ////////////////////////////////////////////////////
if (certSpec.caCert) {
extensions.add(CertificateExtensions.BASIC_CONSTRAINTS, true, new ASN1Sequence(new ASN1Boolean(true)));
}
// ////////////////////////////////////////////////////
if (!certSpec.keyUsageSet.isEmpty()) {
int i = 0;
for (KeyUsageBits kubit : certSpec.keyUsageSet) {
i |= 1 << kubit.ordinal();
}
byte[] keyUsage = new byte[i > 255 ? 2 : 1];
keyUsage[0] = reverseBits(i);
if (i > 255) {
keyUsage[1] = reverseBits(i >> 8);
}
extensions.add(CertificateExtensions.KEY_USAGE, true, new ASN1BitString(keyUsage));
}
// ////////////////////////////////////////////////////
if (!certSpec.extendedKeyUsageSet.isEmpty()) {
int i = 0;
BaseASN1Object[] ekus = new BaseASN1Object[certSpec.extendedKeyUsageSet.size()];
for (ExtendedKeyUsages eku : certSpec.extendedKeyUsageSet.toArray(new ExtendedKeyUsages[0])) {
ekus[i++] = new ASN1ObjectID(eku.getOID());
}
extensions.add(CertificateExtensions.EXTENDED_KEY_USAGE, false, new ASN1Sequence(ekus));
}
// ////////////////////////////////////////////////////
if (certSpec.skiExtension) {
extensions.add(CertificateExtensions.SUBJECT_KEY_IDENTIFIER, createKeyID(subjectPublicKey));
}
// ////////////////////////////////////////////////////
if (certSpec.akiExtension) {
extensions.add(CertificateExtensions.AUTHORITY_KEY_IDENTIFIER, new ASN1Sequence(new SimpleContextSpecific(0, createKeyID(issuerPublicKey))));
}
// ////////////////////////////////////////////////////
if (!certSpec.subjectAltName.isEmpty()) {
int i = 0;
BaseASN1Object[] san = new BaseASN1Object[certSpec.subjectAltName.size()];
for (CertSpec.NameValue nameValue : certSpec.subjectAltName) {
int type = nameValue.name;
// We currently only handle simple IA5String types.
if (type == SubjectAltNameTypes.RFC822_NAME || type == SubjectAltNameTypes.DNS_NAME || type == SubjectAltNameTypes.UNIFORM_RESOURCE_IDENTIFIER) {
if (!(nameValue.value instanceof ASN1IA5String)) {
throw new IOException("Wrong argument type to SubjectAltNames of type " + type);
}
} else // Or IP addresses.
if (type == SubjectAltNameTypes.IP_ADDRESS) {
if (!(nameValue.value instanceof ASN1OctetString)) {
throw new IOException("Wrong argument type to SubjectAltNames of type IP address");
}
} else {
throw new IOException("SubjectAltNames of type " + type + " are not handled.");
}
san[i++] = new SimpleContextSpecific(type, nameValue.value);
}
extensions.add(CertificateExtensions.SUBJECT_ALT_NAME, new ASN1Sequence(san));
}
// ////////////////////////////////////////////////////
if (!certSpec.certPolicyOids.isEmpty()) {
int i = 0;
BaseASN1Object[] policies = new BaseASN1Object[certSpec.certPolicyOids.size()];
for (String oid : certSpec.certPolicyOids) {
policies[i++] = new ASN1Sequence(new ASN1ObjectID(oid));
}
extensions.add(CertificateExtensions.CERTIFICATE_POLICIES, new ASN1Sequence(policies));
}
// ////////////////////////////////////////////////////
if (!certSpec.aiaLocators.isEmpty()) {
int i = 0;
BaseASN1Object[] locators = new BaseASN1Object[certSpec.aiaLocators.size()];
for (String[] loc_info : certSpec.aiaLocators) {
locators[i++] = new ASN1Sequence(new BaseASN1Object[] { new ASN1ObjectID(loc_info[0]), new SimpleContextSpecific(6, new ASN1IA5String(loc_info[1])) });
}
extensions.add(CertificateExtensions.AUTHORITY_INFO_ACCESS, new ASN1Sequence(locators));
}
// ////////////////////////////////////////////////////
if (!certSpec.crlDistPoints.isEmpty()) {
int i = 0;
BaseASN1Object[] cdps = new BaseASN1Object[certSpec.crlDistPoints.size()];
for (String uri : certSpec.crlDistPoints) {
cdps[i++] = new ASN1Sequence(new CompositeContextSpecific(0, new CompositeContextSpecific(0, new SimpleContextSpecific(6, new ASN1IA5String(uri)))));
}
extensions.add(CertificateExtensions.CRL_DISTRIBUTION_POINTS, new ASN1Sequence(cdps));
}
// ////////////////////////////////////////////////////
// Certificate Creation!
// ////////////////////////////////////////////////////
BaseASN1Object[] inner = new BaseASN1Object[extensions.isEmpty() ? 7 : 8];
inner[0] = version;
inner[1] = new ASN1Integer(serialNumber);
inner[2] = signatureAlgorithm;
inner[3] = issuerName.toASN1();
inner[4] = validity;
inner[5] = subjectName.toASN1();
inner[6] = subjectPublicKeyInfo;
if (!extensions.isEmpty()) {
inner[7] = new CompositeContextSpecific(3, extensions.getExtensionData());
}
BaseASN1Object tbsCertificate = new ASN1Sequence(inner);
BaseASN1Object signature = new ASN1BitString(signer.signData(tbsCertificate.encode()));
byte[] certificate = new ASN1Sequence(new BaseASN1Object[] { tbsCertificate, signatureAlgorithm, signature }).encode();
return CertificateUtil.getCertificateFromBlob(certificate);
}
use of com.unboundid.asn1.ASN1BitString in project candlepin by candlepin.
the class X509CRLStreamWriter method preScan.
public synchronized X509CRLStreamWriter preScan(InputStream crlToChange, CRLEntryValidator validator) throws IOException {
if (locked) {
throw new IllegalStateException("Cannot modify a locked stream.");
}
if (preScanned) {
throw new IllegalStateException("preScan has already been run.");
}
X509CRLEntryStream reaperStream = null;
ASN1InputStream asn1In = null;
try {
reaperStream = new X509CRLEntryStream(crlToChange);
if (!reaperStream.hasNext()) {
emptyCrl = true;
preScanned = true;
return this;
}
while (reaperStream.hasNext()) {
CRLEntry entry = reaperStream.next();
if (validator != null && validator.shouldDelete(entry)) {
// Get the serial number
deletedEntries.add(entry.getUserCertificate().getValue());
deletedEntriesLength += entry.getEncoded().length;
}
}
/* At this point, crlToChange is at the point where the crlExtensions would
* be. RFC 5280 says that "Conforming CRL issuers are REQUIRED to include
* the authority key identifier (Section 5.2.1) and the CRL number (Section 5.2.3)
* extensions in all CRLs issued.
*/
byte[] oldExtensions = null;
ASN1Primitive o;
asn1In = new ASN1InputStream(crlToChange);
while ((o = asn1In.readObject()) != null) {
if (o instanceof ASN1Sequence) {
// Now we are at the signatureAlgorithm
ASN1Sequence seq = (ASN1Sequence) o;
if (seq.getObjectAt(0) instanceof ASN1ObjectIdentifier) {
// It's possible an algorithm has already been set using setSigningAlgorithm()
if (signingAlg == null) {
signingAlg = AlgorithmIdentifier.getInstance(seq);
}
try {
// Build the signer
this.signer = createContentSigner(signingAlg, key);
} catch (OperatorCreationException e) {
throw new IOException("Could not create ContentSigner for " + signingAlg.getAlgorithm());
}
}
} else if (o instanceof ASN1BitString) {
oldSigLength = o.getEncoded().length;
} else {
if (oldExtensions != null) {
throw new IllegalStateException("Already read in CRL extensions.");
}
oldExtensions = o.getEncoded();
}
}
if (oldExtensions == null) {
/* v1 CRLs (defined in RFC 1422) don't require extensions but all new
* CRLs should be v2 (defined in RFC 5280). In the extremely unlikely
* event that someone is working with a v1 CRL, we handle it here although
* we print a warning.
*/
preScanned = true;
newExtensions = null;
extensionsDelta = 0;
log.warn("The CRL you are modifying is a version 1 CRL." + " Please investigate moving to a version 2 CRL by adding the CRL Number" + " and Authority Key Identifier extensions.");
return this;
}
newExtensions = updateExtensions(oldExtensions);
// newExtension and oldExtensions have already been converted to DER so any difference
// in the length of the L bytes will be accounted for in the overall difference between
// the length of the two byte arrays.
extensionsDelta = newExtensions.length - oldExtensions.length;
} finally {
if (reaperStream != null) {
reaperStream.close();
}
IOUtils.closeQuietly(asn1In);
}
preScanned = true;
return this;
}
use of com.unboundid.asn1.ASN1BitString in project xipki by xipki.
the class GrandCertTemplateBuilder method create.
GrantedCertTemplate create(IdentifiedCertprofile certprofile, CertTemplateData certTemplate, RequestorInfo requestor, List<KeypairGenerator> keypairGenerators, boolean update) throws OperationException {
if (caInfo.getRevocationInfo() != null) {
throw new OperationException(NOT_PERMITTED, "CA is revoked");
}
if (certprofile == null) {
throw new OperationException(UNKNOWN_CERT_PROFILE, "unknown cert profile " + certTemplate.getCertprofileName());
}
ConcurrentContentSigner signer = caInfo.getSigner(certprofile.getSignatureAlgorithms());
if (signer == null) {
throw new OperationException(SYSTEM_FAILURE, "CA does not support any signature algorithm restricted by the cert profile");
}
final NameId certprofileIdent = certprofile.getIdent();
if (certprofile.getVersion() != Certprofile.X509CertVersion.v3) {
throw new OperationException(SYSTEM_FAILURE, "unknown cert version " + certprofile.getVersion());
}
if (certprofile.isOnlyForRa()) {
if (requestor == null || !requestor.isRa()) {
throw new OperationException(NOT_PERMITTED, "profile " + certprofileIdent + " not applied to non-RA");
}
}
switch(certprofile.getCertLevel()) {
case RootCA:
throw new OperationException(NOT_PERMITTED, "CA is not allowed to generate Root CA certificate");
case SubCA:
Integer reqPathlen = certprofile.getPathLenBasicConstraint();
int caPathLen = caInfo.getPathLenConstraint();
boolean allowed = (reqPathlen == null && caPathLen == Integer.MAX_VALUE) || (reqPathlen != null && reqPathlen < caPathLen);
if (!allowed) {
throw new OperationException(NOT_PERMITTED, "invalid BasicConstraint.pathLenConstraint");
}
break;
default:
}
X500Name requestedSubject = CaUtil.removeEmptyRdns(certTemplate.getSubject());
if (!certprofile.isSerialNumberInReqPermitted()) {
RDN[] rdns = requestedSubject.getRDNs(ObjectIdentifiers.DN.SN);
if (rdns != null && rdns.length > 0) {
throw new OperationException(BAD_CERT_TEMPLATE, "subjectDN SerialNumber in request is not permitted");
}
}
Date reqNotBefore = certTemplate.getNotBefore();
Date grantedNotBefore = certprofile.getNotBefore(reqNotBefore);
// notBefore in the past is not permitted (due to the fact that some clients may not have
// accurate time, we allow max. 5 minutes in the past)
long currentMillis = System.currentTimeMillis();
if (currentMillis - grantedNotBefore.getTime() > MS_PER_10MINUTES) {
grantedNotBefore = new Date(currentMillis - MS_PER_10MINUTES);
}
long time = caInfo.getNoNewCertificateAfter();
if (grantedNotBefore.getTime() > time) {
throw new OperationException(NOT_PERMITTED, "CA is not permitted to issue certificate after " + new Date(time));
}
if (grantedNotBefore.before(caInfo.getNotBefore())) {
// notBefore may not be before CA's notBefore
grantedNotBefore = caInfo.getNotBefore();
}
PrivateKeyInfo privateKey = null;
SubjectPublicKeyInfo grantedPublicKeyInfo = certTemplate.getPublicKeyInfo();
if (grantedPublicKeyInfo != null) {
try {
grantedPublicKeyInfo = X509Util.toRfc3279Style(certTemplate.getPublicKeyInfo());
} catch (InvalidKeySpecException ex) {
LogUtil.warn(LOG, ex, "invalid SubjectPublicKeyInfo");
throw new OperationException(BAD_CERT_TEMPLATE, "invalid SubjectPublicKeyInfo");
}
// CHECK weak public key, like RSA key (ROCA)
if (grantedPublicKeyInfo.getAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.rsaEncryption)) {
try {
ASN1Sequence seq = ASN1Sequence.getInstance(grantedPublicKeyInfo.getPublicKeyData().getOctets());
if (seq.size() != 2) {
throw new OperationException(BAD_CERT_TEMPLATE, "invalid format of RSA public key");
}
BigInteger modulus = ASN1Integer.getInstance(seq.getObjectAt(0)).getPositiveValue();
if (RSABrokenKey.isAffected(modulus)) {
throw new OperationException(BAD_CERT_TEMPLATE, "RSA public key is too weak");
}
} catch (IllegalArgumentException ex) {
throw new OperationException(BAD_CERT_TEMPLATE, "invalid format of RSA public key");
}
}
} else if (certTemplate.isCaGenerateKeypair()) {
KeypairGenControl kg = certprofile.getKeypairGenControl();
ASN1ObjectIdentifier keyAlgOid;
String keyspec;
if (kg == null || kg instanceof KeypairGenControl.ForbiddenKeypairGenControl) {
throw new OperationException(BAD_CERT_TEMPLATE, "no public key is specified");
}
if (kg instanceof KeypairGenControl.InheritCAKeypairGenControl) {
keyspec = keyspecByImplicitCA;
keyAlgOid = keyAlgOidByImplicitCA;
} else {
keyspec = kg.getKeyspec();
keyAlgOid = kg.getKeyAlgorithmOid();
}
KeypairGenerator keypairGenerator = null;
if (keypairGenerators != null) {
for (KeypairGenerator m : keypairGenerators) {
if (m.supports(keyspec)) {
keypairGenerator = m;
break;
}
}
}
if (keypairGenerator == null) {
throw new OperationException(SYSTEM_FAILURE, "found no keypair generator for keyspec " + keyspec);
}
String name = keypairGenerator.getName();
try {
privateKey = keypairGenerator.generateKeypair(keyspec);
LOG.info("generated keypair {} with generator {}", keyspec, name);
} catch (XiSecurityException ex) {
String msg = "error generating keypair " + keyspec + " using generator " + name;
LogUtil.error(LOG, ex, msg);
throw new OperationException(SYSTEM_FAILURE, msg);
}
// adapt the algorithm identifier in private key and public key
if (!privateKey.getPrivateKeyAlgorithm().getAlgorithm().equals(keyAlgOid)) {
ASN1BitString asn1PublicKeyData = privateKey.getPublicKeyData();
try {
privateKey = new PrivateKeyInfo(new AlgorithmIdentifier(keyAlgOid, privateKey.getPrivateKeyAlgorithm().getParameters()), privateKey.getPrivateKey().toASN1Primitive(), privateKey.getAttributes(), asn1PublicKeyData == null ? null : asn1PublicKeyData.getOctets());
} catch (IOException ex) {
throw new OperationException(SYSTEM_FAILURE, ex);
}
}
// construct SubjectPublicKeyInfo
String keyType = keyspec.split("/")[0].toUpperCase(Locale.ROOT);
byte[] publicKeyData;
switch(keyType) {
case "RSA":
{
RSAPrivateKey sk = RSAPrivateKey.getInstance(privateKey.getPrivateKey().getOctets());
try {
publicKeyData = new RSAPublicKey(sk.getModulus(), sk.getPublicExponent()).getEncoded();
} catch (IOException ex) {
throw new OperationException(SYSTEM_FAILURE, ex);
}
break;
}
case "EC":
{
ECPrivateKey sk = ECPrivateKey.getInstance(privateKey.getPrivateKey().getOctets());
publicKeyData = sk.getPublicKey().getBytes();
break;
}
case "DSA":
case "ED25519":
case "ED448":
case "X25519":
case "X448":
{
publicKeyData = privateKey.getPublicKeyData().getBytes();
break;
}
default:
throw new IllegalStateException("unknown key type " + keyType);
}
grantedPublicKeyInfo = new SubjectPublicKeyInfo(privateKey.getPrivateKeyAlgorithm(), publicKeyData);
try {
grantedPublicKeyInfo = X509Util.toRfc3279Style(grantedPublicKeyInfo);
} catch (InvalidKeySpecException ex) {
throw new OperationException(SYSTEM_FAILURE, ex);
}
} else {
// show not reach here
throw new OperationException(BAD_CERT_TEMPLATE, "no public key is specified");
}
// public key
try {
grantedPublicKeyInfo = certprofile.checkPublicKey(grantedPublicKeyInfo);
} catch (CertprofileException ex) {
throw new OperationException(SYSTEM_FAILURE, "exception in cert profile " + certprofileIdent);
} catch (BadCertTemplateException ex) {
throw new OperationException(BAD_CERT_TEMPLATE, ex);
}
// subject
Certprofile.SubjectInfo subjectInfo;
try {
subjectInfo = certprofile.getSubject(requestedSubject, grantedPublicKeyInfo);
} catch (CertprofileException ex) {
throw new OperationException(SYSTEM_FAILURE, "exception in cert profile " + certprofileIdent);
} catch (BadCertTemplateException ex) {
throw new OperationException(BAD_CERT_TEMPLATE, ex);
}
X500Name grantedSubject = subjectInfo.getGrantedSubject();
// make sure that empty subject is not permitted
ASN1ObjectIdentifier[] attrTypes = grantedSubject.getAttributeTypes();
if (attrTypes == null || attrTypes.length == 0) {
throw new OperationException(BAD_CERT_TEMPLATE, "empty subject is not permitted");
}
// make sure that the grantedSubject does not equal the CA's subject
if (X509Util.canonicalizName(grantedSubject).equals(caInfo.getPublicCaInfo().getC14nSubject())) {
throw new OperationException(ALREADY_ISSUED, "certificate with the same subject as CA is not allowed");
}
if (update) {
CertStore.CertStatus certStatus = certstore.getCertStatusForSubject(caInfo.getIdent(), grantedSubject);
if (certStatus == CertStore.CertStatus.REVOKED) {
throw new OperationException(CERT_REVOKED);
} else if (certStatus == CertStore.CertStatus.UNKNOWN) {
throw new OperationException(UNKNOWN_CERT);
}
}
// end if(update)
StringBuilder msgBuilder = new StringBuilder();
if (subjectInfo.getWarning() != null) {
msgBuilder.append(", ").append(subjectInfo.getWarning());
}
Validity validity = certprofile.getValidity();
if (validity == null) {
validity = caInfo.getMaxValidity();
} else if (validity.compareTo(caInfo.getMaxValidity()) > 0) {
validity = caInfo.getMaxValidity();
}
Date maxNotAfter = validity.add(grantedNotBefore);
// maxNotAfter not after 99991231-235959
if (maxNotAfter.getTime() > MAX_CERT_TIME_MS) {
maxNotAfter = MAX_CERT_TIME;
}
Date grantedNotAfter = certTemplate.getNotAfter();
if (grantedNotAfter != null) {
if (grantedNotAfter.after(maxNotAfter)) {
grantedNotAfter = maxNotAfter;
msgBuilder.append(", notAfter modified");
}
} else {
grantedNotAfter = maxNotAfter;
}
if (grantedNotAfter.after(caInfo.getNotAfter())) {
ValidityMode caMode = caInfo.getValidityMode();
NotAfterMode profileMode = certprofile.getNotAfterMode();
if (profileMode == null) {
profileMode = NotAfterMode.BY_CA;
}
if (profileMode == NotAfterMode.STRICT) {
throw new OperationException(NOT_PERMITTED, "notAfter outside of CA's validity is not permitted by the CertProfile");
}
if (caMode == ValidityMode.STRICT) {
throw new OperationException(NOT_PERMITTED, "notAfter outside of CA's validity is not permitted by the CA");
}
if (caMode == ValidityMode.CUTOFF) {
grantedNotAfter = caInfo.getNotAfter();
} else if (caMode == ValidityMode.LAX) {
if (profileMode == NotAfterMode.CUTOFF) {
grantedNotAfter = caInfo.getNotAfter();
}
} else {
throw new IllegalStateException("should not reach here, CA ValidityMode " + caMode + " CertProfile NotAfterMode " + profileMode);
}
// end if (mode)
}
// end if (notAfter)
String warning = null;
if (msgBuilder.length() > 2) {
warning = msgBuilder.substring(2);
}
GrantedCertTemplate gct = new GrantedCertTemplate(certTemplate.getExtensions(), certprofile, grantedNotBefore, grantedNotAfter, requestedSubject, grantedPublicKeyInfo, privateKey, signer, warning);
gct.setGrantedSubject(grantedSubject);
return gct;
}
Aggregations