When dealing with self-signed certificate chains in enterprise environments, we often face the security concern of over-permissive root certificates. The standard PKI implementation doesn't natively provide domain restriction at the root CA level, but several technical workarounds exist.
The most reliable method is implementing certificate pinning at the application level. Here's a Python example using requests:
import requests
import ssl
from requests.adapters import HTTPAdapter
from urllib3.util.ssl_ import create_urllib3_context
class PinnedAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
context = create_urllib3_context()
context.load_verify_locations(cafile='/path/to/root.crt')
kwargs['ssl_context'] = context
return super().init_poolmanager(*args, **kwargs)
session = requests.Session()
session.mount('https://specific.domain.com', PinnedAdapter())
For X.509 certificates, you can define Name Constraints extensions in your root certificate during creation:
openssl req -x509 -newkey rsa:4096 \
-extensions v3_ca \
-keyout root.key -out root.pem \
-days 3650 -nodes \
-addext "nameConstraints=permitted;DNS:.specific.domain.com"
Create an intermediate CA with domain restrictions that chains to your root:
[ v3_intermediate_ca ]
basicConstraints = critical,CA:true,pathlen:0
nameConstraints = critical,permitted;DNS:.specific.domain.com
keyUsage = critical,keyCertSign,cRLSign
On Linux systems, you can modify the OpenSSL configuration:
[default_ssl]
verify = 2
x509_strict = 1
Use certutil to restrict usage:
certutil -setreg chain\ChainCacheResyncFiletime @now
certutil -f -dstemplate "DomainRestricted" rootCA.cer
For web applications, combine CAA records with certificate transparency:
example.com. IN CAA 0 issue "ca.example.net"
Implement periodic checks with openssl commands:
openssl verify -CAfile root.crt -untrusted intermediate.crt domain.crt
When dealing with self-signed certificates in enterprise applications, we often face a security dilemma: installing a root CA certificate grants it universal trust, but we may only need it to validate certificates for specific domains. The default behavior in most systems (like Windows Certificate Store or OpenSSL) treats root CA certificates as globally trusted authorities.
While certificate pinning is a common solution, it operates at the application level. What we need is a way to modify the system's trust store behavior to limit validation scope:
# Example of OpenSSL config that could theoretically restrict validation
openssl x509 -in rootCA.pem -addtrust serverAuth \
-addreject clientAuth -out restrictedCA.pem
Windows Certificate Store Method
For Windows environments, we can use certificate store flags:
# PowerShell to install cert with enhanced key usage restrictions
Import-Certificate -FilePath "C:\path\to\rootCA.cer" -CertStoreLocation Cert:\LocalMachine\Root -Property @("2.5.29.37={text}1.3.6.1.5.5.7.3.1")
Linux/OpenSSL Alternative
Create a custom OpenSSL config that whitelists domains:
# openssl-restricted.cnf
[req]
...
[alt_names]
DNS.1 = allowed.example.com
DNS.2 = *.specific.org
When system-level restrictions aren't sufficient, implement domain validation in your application:
// C# example of domain-specific validation
ServicePointManager.ServerCertificateValidationCallback +=
(sender, cert, chain, errors) =>
{
return cert.Subject.Contains("CN=specific.domain.com")
&& errors == SslPolicyErrors.None;
};
Remember that any restriction mechanism should:
- Maintain CRL/OCSP checking
- Not interfere with certificate revocation
- Log all validation failures