use of org.gudy.bouncycastle.asn1.x509.GeneralName in project candlepin by candlepin.
the class BouncyCastlePKIUtility method createX509Certificate.
@Override
public X509Certificate createX509Certificate(String dn, Set<X509ExtensionWrapper> extensions, Set<X509ByteExtensionWrapper> byteExtensions, Date startDate, Date endDate, KeyPair clientKeyPair, BigInteger serialNumber, String alternateName) throws GeneralSecurityException, IOException {
X509Certificate caCert = reader.getCACert();
byte[] publicKeyEncoded = clientKeyPair.getPublic().getEncoded();
X509v3CertificateBuilder certGen = new X509v3CertificateBuilder(X500Name.getInstance(caCert.getSubjectX500Principal().getEncoded()), serialNumber, startDate, endDate, new X500Name(dn), SubjectPublicKeyInfo.getInstance(publicKeyEncoded));
// set key usage - required for proper x509 function
KeyUsage keyUsage = new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.dataEncipherment);
// add SSL extensions - required for proper x509 function
NetscapeCertType certType = new NetscapeCertType(NetscapeCertType.sslClient | NetscapeCertType.smime);
certGen.addExtension(MiscObjectIdentifiers.netscapeCertType, false, certType);
certGen.addExtension(Extension.keyUsage, false, keyUsage);
JcaX509ExtensionUtils extensionUtil = new JcaX509ExtensionUtils();
AuthorityKeyIdentifier aki = extensionUtil.createAuthorityKeyIdentifier(caCert);
certGen.addExtension(Extension.authorityKeyIdentifier, false, aki.getEncoded());
certGen.addExtension(Extension.subjectKeyIdentifier, false, subjectKeyWriter.getSubjectKeyIdentifier(clientKeyPair, extensions));
certGen.addExtension(Extension.extendedKeyUsage, false, new ExtendedKeyUsage(KeyPurposeId.id_kp_clientAuth));
// Add an additional alternative name if provided.
if (alternateName != null) {
/*
Why add the certificate subject again as an alternative name? RFC 6125 Section 6.4.4
stipulates that if SANs are provided, a validator MUST use them instead of the certificate
subject. If no SANs are present, the RFC allows the validator to use the subject field. So,
if we do have an SAN to add, we need to add the subject field again as an SAN.
See http://stackoverflow.com/questions/5935369 and
https://tools.ietf.org/html/rfc6125#section-6.4.4 and
NB: These extensions should *not* be marked critical since the subject field is not empty.
*/
GeneralName subject = new GeneralName(GeneralName.directoryName, dn);
GeneralName name = new GeneralName(GeneralName.directoryName, "CN=" + alternateName);
ASN1Encodable[] altNameArray = { subject, name };
GeneralNames altNames = GeneralNames.getInstance(new DERSequence(altNameArray));
certGen.addExtension(Extension.subjectAlternativeName, false, altNames);
}
if (extensions != null) {
for (X509ExtensionWrapper wrapper : extensions) {
// Bouncycastle hates null values. So, set them to blank
// if they are null
String value = wrapper.getValue() == null ? "" : wrapper.getValue();
certGen.addExtension(wrapper.toASN1Primitive(), wrapper.isCritical(), new DERUTF8String(value));
}
}
if (byteExtensions != null) {
for (X509ByteExtensionWrapper wrapper : byteExtensions) {
// Bouncycastle hates null values. So, set them to blank
// if they are null
byte[] value = wrapper.getValue() == null ? new byte[0] : wrapper.getValue();
certGen.addExtension(wrapper.toASN1Primitive(), wrapper.isCritical(), new DEROctetString(value));
}
}
JcaContentSignerBuilder builder = new JcaContentSignerBuilder(SIGNATURE_ALGO).setProvider(BC_PROVIDER);
ContentSigner signer;
try {
signer = builder.build(reader.getCaKey());
} catch (OperatorCreationException e) {
throw new IOException(e);
}
// Generate the certificate
return new JcaX509CertificateConverter().getCertificate(certGen.build(signer));
}
use of org.gudy.bouncycastle.asn1.x509.GeneralName in project credhub by cloudfoundry-incubator.
the class CertificateReaderTest method returnsParametersCorrectly.
@Test
public void returnsParametersCorrectly() {
final String distinguishedName = "O=test-org, ST=Jupiter, C=MilkyWay, CN=test-common-name, OU=test-org-unit, L=Europa";
final GeneralNames generalNames = new GeneralNames(new GeneralName(GeneralName.dNSName, "SolarSystem"));
CertificateReader certificateReader = new CertificateReader(CertificateStringConstants.BIG_TEST_CERT);
assertThat(certificateReader.getAlternativeNames(), equalTo(generalNames));
assertThat(asList(certificateReader.getExtendedKeyUsage().getUsages()), containsInAnyOrder(KeyPurposeId.id_kp_serverAuth, KeyPurposeId.id_kp_clientAuth));
assertThat(certificateReader.getKeyUsage().hasUsages(KeyUsage.digitalSignature), equalTo(true));
assertThat(certificateReader.getSubjectName().toString(), equalTo(distinguishedName));
}
use of org.gudy.bouncycastle.asn1.x509.GeneralName in project jruby-openssl by jruby.
the class X509Cert method uniqueExtensions.
private Collection<X509Extension> uniqueExtensions() {
final Map<ASN1ObjectIdentifier, X509Extension> unique = new LinkedHashMap<ASN1ObjectIdentifier, X509Extension>();
for (X509Extension current : this.extensions) {
final ASN1ObjectIdentifier oid = current.getRealObjectID();
final X509Extension existing = unique.get(oid);
if (existing == null) {
unique.put(oid, current);
continue;
}
// commonly used e.g. with subjectAltName || issuserAltName :
if ("2.5.29.17".equals(oid.getId()) || "2.5.29.18".equals(oid.getId())) {
final ASN1EncodableVector vec = new ASN1EncodableVector();
try {
GeneralName[] n1 = extRealNames(existing);
for (int i = 0; i < n1.length; i++) vec.add(n1[i]);
GeneralName[] n2 = extRealNames(current);
for (int i = 0; i < n2.length; i++) vec.add(n2[i]);
GeneralNames nn = GeneralNames.getInstance(new DLSequence(vec));
final X509Extension existingDup = existing.clone();
existingDup.setRealValue(nn);
unique.put(oid, existingDup);
} catch (IOException ex) {
throw getRuntime().newIOErrorFromException(ex);
}
continue;
}
// TODO do we need special care for any others here ?!?
final ASN1EncodableVector vec = new ASN1EncodableVector();
try {
final ASN1Encodable existingValue = existing.getRealValue();
if (existingValue instanceof ASN1Sequence) {
final ASN1Sequence seq = (ASN1Sequence) existingValue;
for (int i = 0; i < seq.size(); i++) {
vec.add(seq.getObjectAt(i));
}
} else {
vec.add(existingValue);
}
vec.add(current.getRealValue());
// existing.setRealValue( new DLSequence(vec) );
final X509Extension existingDup = existing.clone();
existingDup.setRealValue(new DLSequence(vec));
unique.put(oid, existingDup);
} catch (IOException ex) {
throw getRuntime().newIOErrorFromException(ex);
}
}
return unique.values();
}
use of org.gudy.bouncycastle.asn1.x509.GeneralName in project jruby-openssl by jruby.
the class X509Extension method value.
@JRubyMethod
public RubyString value(final ThreadContext context) {
if (this.value instanceof RubyString) {
// return the same as set
return (RubyString) this.value;
}
final Ruby runtime = context.runtime;
final String oid = getRealObjectID().getId();
try {
if (oid.equals("2.5.29.19")) {
// basicConstraints
ASN1Sequence seq2 = (ASN1Sequence) ASN1.readObject(getRealValueEncoded());
final ByteList val = new ByteList(32);
if (seq2.size() > 0) {
val.append(CA_);
ASN1Encodable obj0 = seq2.getObjectAt(0);
final boolean bool;
if (obj0 instanceof ASN1Boolean) {
bool = ((ASN1Boolean) obj0).isTrue();
} else {
// NOTE: keep it due BC <= 1.50
bool = ((DERBoolean) obj0).isTrue();
}
val.append(bool ? TRUE : FALSE);
}
if (seq2.size() > 1) {
val.append(", pathlen:".getBytes());
val.append(seq2.getObjectAt(1).toString().getBytes());
}
return runtime.newString(val);
}
if (oid.equals("2.5.29.15")) {
// keyUsage
final byte[] enc = getRealValueEncoded();
byte b3 = 0;
byte b2 = enc[2];
if (enc.length > 3)
b3 = enc[3];
final ByteList val = new ByteList(64);
byte[] sep = _;
if ((b2 & (byte) 128) != 0) {
val.append(sep);
val.append(Decipher_Only);
sep = SEP;
}
if ((b3 & (byte) 128) != 0) {
val.append(sep);
val.append(Digital_Signature);
sep = SEP;
}
if ((b3 & (byte) 64) != 0) {
val.append(sep);
val.append(Non_Repudiation);
sep = SEP;
}
if ((b3 & (byte) 32) != 0) {
val.append(sep);
val.append(Key_Encipherment);
sep = SEP;
}
if ((b3 & (byte) 16) != 0) {
val.append(sep);
val.append(Data_Encipherment);
sep = SEP;
}
if ((b3 & (byte) 8) != 0) {
val.append(sep);
val.append(Key_Agreement);
sep = SEP;
}
if ((b3 & (byte) 4) != 0) {
val.append(sep);
val.append(Certificate_Sign);
sep = SEP;
}
if ((b3 & (byte) 2) != 0) {
val.append(sep);
val.append(CRL_Sign);
sep = SEP;
}
if ((b3 & (byte) 1) != 0) {
// sep = SEP;
val.append(sep);
// sep = SEP;
val.append(Encipher_Only);
}
return runtime.newString(val);
}
if (oid.equals("2.16.840.1.113730.1.1")) {
// nsCertType
final byte b0 = getRealValueEncoded()[0];
final ByteList val = new ByteList(64);
byte[] sep = _;
if ((b0 & (byte) 128) != 0) {
val.append(sep);
val.append(SSL_Client);
sep = SEP;
}
if ((b0 & (byte) 64) != 0) {
val.append(sep);
val.append(SSL_Server);
sep = SEP;
}
if ((b0 & (byte) 32) != 0) {
val.append(sep);
val.append(SMIME);
sep = SEP;
}
if ((b0 & (byte) 16) != 0) {
val.append(sep);
val.append(Object_Signing);
sep = SEP;
}
if ((b0 & (byte) 8) != 0) {
val.append(sep);
val.append(Unused);
sep = SEP;
}
if ((b0 & (byte) 4) != 0) {
val.append(sep);
val.append(SSL_CA);
sep = SEP;
}
if ((b0 & (byte) 2) != 0) {
val.append(sep);
val.append(SMIME_CA);
sep = SEP;
}
if ((b0 & (byte) 1) != 0) {
val.append(sep);
val.append(Object_Signing_CA);
}
return runtime.newString(val);
}
if (oid.equals("2.5.29.14")) {
// subjectKeyIdentifier
ASN1Encodable value = getRealValue();
if (value instanceof ASN1OctetString) {
byte[] octets = ((ASN1OctetString) value).getOctets();
if (octets.length > 0 && octets[0] == BERTags.OCTET_STRING) {
// read nested octets
value = ASN1.readObject(octets);
}
}
return runtime.newString(hexBytes(keyidBytes(value.toASN1Primitive()), 0));
}
if (oid.equals("2.5.29.35")) {
// authorityKeyIdentifier
ASN1Encodable value = getRealValue();
if (value instanceof ASN1OctetString) {
value = ASN1.readObject(((ASN1OctetString) value).getOctets());
}
final ByteList val = new ByteList(72);
val.append(keyid_);
if (value instanceof ASN1Sequence) {
final ASN1Sequence seq = (ASN1Sequence) value;
final int size = seq.size();
if (size == 0)
return RubyString.newEmptyString(runtime);
ASN1Primitive keyid = seq.getObjectAt(0).toASN1Primitive();
hexBytes(keyidBytes(keyid), val).append('\n');
for (int i = 1; i < size; i++) {
final ASN1Encodable issuer = seq.getObjectAt(i);
// NOTE: blindly got OpenSSL tests passing (likely in-complete) :
if (issuer instanceof ASN1TaggedObject) {
ASN1Primitive obj = ((ASN1TaggedObject) issuer).getObject();
switch(((ASN1TaggedObject) issuer).getTagNo()) {
case 1:
if (obj instanceof ASN1TaggedObject) {
formatGeneralName(GeneralName.getInstance(obj), val, true);
}
break;
case // serial
2:
val.append(new byte[] { 's', 'e', 'r', 'i', 'a', 'l', ':' });
if (obj instanceof ASN1Integer) {
hexBytes(((ASN1Integer) obj).getValue().toByteArray(), val);
} else {
hexBytes(((ASN1OctetString) obj).getOctets(), val);
}
break;
}
}
val.append('\n');
}
return runtime.newString(val);
}
hexBytes(keyidBytes(value.toASN1Primitive()), val).append('\n');
return runtime.newString(val);
}
if (oid.equals("2.5.29.21")) {
// CRLReason
final IRubyObject value = getValue(runtime);
switch(RubyNumeric.fix2int(value)) {
case 0:
return runtime.newString(new ByteList(Unspecified));
case 1:
return RubyString.newString(runtime, "Key Compromise");
case 2:
return RubyString.newString(runtime, "CA Compromise");
case 3:
return RubyString.newString(runtime, "Affiliation Changed");
case 4:
return RubyString.newString(runtime, "Superseded");
case 5:
return RubyString.newString(runtime, "Cessation Of Operation");
case 6:
return RubyString.newString(runtime, "Certificate Hold");
case 8:
return RubyString.newString(runtime, "Remove From CRL");
case 9:
return RubyString.newString(runtime, "Privilege Withdrawn");
default:
return runtime.newString(new ByteList(Unspecified));
}
}
if (oid.equals("2.5.29.17") || oid.equals("2.5.29.18")) {
// subjectAltName || issuerAltName
try {
ASN1Encodable value = getRealValue();
final ByteList val = new ByteList(64);
if (value instanceof ASN1TaggedObject) {
formatGeneralName(GeneralName.getInstance(value), val, false);
return runtime.newString(val);
}
if (value instanceof GeneralName) {
formatGeneralName((GeneralName) value, val, false);
return runtime.newString(val);
}
if (value instanceof ASN1OctetString) {
// decoded octets will end up as an ASN1Sequence instance :
value = ASN1.readObject(((ASN1OctetString) value).getOctets());
}
if (value instanceof ASN1TaggedObject) {
// DERTaggedObject (issuerAltName wrapping)
formatGeneralName(GeneralName.getInstance(value), val, false);
return runtime.newString(val);
}
final GeneralName[] names = GeneralNames.getInstance(value).getNames();
for (int i = 0; i < names.length; i++) {
boolean other = formatGeneralName(names[i], val, false);
if (i < names.length - 1) {
if (other)
val.append(';');
else
val.append(',').append(' ');
}
}
return runtime.newString(val);
} catch (IllegalArgumentException e) {
debugStackTrace(runtime, e);
return rawValueAsString(context);
}
}
if (oid.equals("2.5.29.37")) {
// extendedKeyUsage
final ByteList val = new ByteList(64);
if (this.value instanceof ASN1Sequence) {
// opt "short" path
final ASN1Sequence seq = (ASN1Sequence) this.value;
final int size = seq.size();
for (int i = 0; i < size; i++) {
ASN1Encodable o = seq.getObjectAt(i);
String name = o.toString();
Integer nid = ASN1.oid2nid(runtime, new ASN1ObjectIdentifier(name));
if (nid != null)
name = ASN1.nid2ln(runtime, nid);
if (name == null)
name = o.toString();
val.append(ByteList.plain(name));
if (i < size - 1)
val.append(',').append(' ');
}
return runtime.newString(val);
}
final IRubyObject value = getValue(runtime);
if (value instanceof RubyArray) {
final RubyArray arr = (RubyArray) value;
final int size = arr.size();
for (int i = 0; i < size; i++) {
IRubyObject entry = arr.eltInternal(i);
if ("ObjectId".equals(entry.getMetaClass().getBaseName())) {
entry = entry.callMethod(context, "ln");
} else if (entry.respondsTo("value")) {
entry = entry.callMethod(context, "value");
}
val.append(entry.asString().getByteList());
if (i < size - 1)
val.append(',').append(' ');
}
}
return runtime.newString(val);
}
return rawValueAsString(context);
} catch (IOException e) {
debugStackTrace(runtime, e);
throw newExtensionError(runtime, e);
}
}
use of org.gudy.bouncycastle.asn1.x509.GeneralName in project jruby-openssl by jruby.
the class OCSPRequest method verify.
@JRubyMethod(name = "verify", rest = true)
public IRubyObject verify(IRubyObject[] args) {
Ruby runtime = getRuntime();
ThreadContext context = runtime.getCurrentContext();
int flags = 0;
boolean ret = false;
if (Arity.checkArgumentCount(runtime, args, 2, 3) == 3) {
flags = RubyFixnum.fix2int((RubyFixnum) args[2]);
}
IRubyObject certificates = args[0];
IRubyObject store = args[1];
OCSPReq bcOCSPReq = getBCOCSPReq();
if (bcOCSPReq == null) {
throw newOCSPError(runtime, new NullPointerException("Missing BC asn1bcReq. Missing certIDs or signature?"));
}
if (!bcOCSPReq.isSigned()) {
return RubyBoolean.newBoolean(runtime, ret);
}
GeneralName genName = bcOCSPReq.getRequestorName();
if (genName.getTagNo() != 4) {
return RubyBoolean.newBoolean(runtime, ret);
}
X500Name genX500Name = X500Name.getInstance(genName.getName());
X509StoreContext storeContext = null;
JcaContentVerifierProviderBuilder jcacvpb = new JcaContentVerifierProviderBuilder();
jcacvpb.setProvider("BC");
try {
java.security.cert.Certificate signer = findCertByName(genX500Name, certificates, flags);
if (signer == null)
return RubyBoolean.newBoolean(runtime, ret);
if ((flags & RubyFixnum.fix2int(_OCSP(runtime).getConstant(OCSP_NOINTERN))) > 0 && ((flags & RubyFixnum.fix2int(_OCSP(runtime).getConstant(OCSP_TRUSTOTHER))) > 0))
flags |= RubyFixnum.fix2int(_OCSP(runtime).getConstant(OCSP_NOVERIFY));
if ((flags & RubyFixnum.fix2int(_OCSP(runtime).getConstant(OCSP_NOSIGS))) == 0) {
PublicKey signerPubKey = signer.getPublicKey();
ContentVerifierProvider cvp = jcacvpb.build(signerPubKey);
ret = bcOCSPReq.isSignatureValid(cvp);
if (!ret) {
return RubyBoolean.newBoolean(runtime, ret);
}
}
if ((flags & RubyFixnum.fix2int(_OCSP(runtime).getConstant(OCSP_NOVERIFY))) == 0) {
if ((flags & RubyFixnum.fix2int(_OCSP(runtime).getConstant(OCSP_NOCHAIN))) > 0) {
storeContext = X509StoreContext.newStoreContext(context, (X509Store) store, X509Cert.wrap(runtime, signer), context.nil);
} else {
RubyArray certs = RubyArray.newEmptyArray(runtime);
ASN1Sequence bcCerts = asn1bcReq.getOptionalSignature().getCerts();
if (bcCerts != null) {
Iterator<ASN1Encodable> it = bcCerts.iterator();
while (it.hasNext()) {
Certificate cert = Certificate.getInstance(it.next());
certs.add(X509Cert.wrap(runtime, new X509AuxCertificate(cert)));
}
}
storeContext = X509StoreContext.newStoreContext(context, (X509Store) store, X509Cert.wrap(runtime, signer), certs);
}
storeContext.set_purpose(context, _X509(runtime).getConstant("PURPOSE_OCSP_HELPER"));
storeContext.set_trust(context, _X509(runtime).getConstant("TRUST_OCSP_REQUEST"));
ret = storeContext.verify(context).isTrue();
if (!ret)
return RubyBoolean.newBoolean(runtime, false);
}
} catch (Exception e) {
debugStackTrace(e);
throw newOCSPError(runtime, e);
}
return RubyBoolean.newBoolean(getRuntime(), ret);
}
Aggregations