Search in sources :

Example 6 with RSAPublicKey

use of com.github.zhenwei.core.asn1.pkcs.RSAPublicKey in project xipki by xipki.

the class GrandCertTemplateBuilder method create.

GrantedCertTemplate create(IdentifiedCertprofile certprofile, CertTemplateData certTemplate, RequestorInfo requestor, 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 certifate after " + new Date(time));
    }
    if (grantedNotBefore.before(caInfo.getNotBefore())) {
        // notBefore may not be before CA's notBefore
        grantedNotBefore = caInfo.getNotBefore();
    }
    PrivateKeyInfo privateKey;
    SubjectPublicKeyInfo grantedPublicKeyInfo = certTemplate.getPublicKeyInfo();
    if (grantedPublicKeyInfo != null) {
        privateKey = 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();
        try {
            if (kg instanceof KeypairGenControl.InheritCAKeypairGenControl) {
                kg = keypairGenControlByImplictCA;
            }
            if (kg == null || kg instanceof KeypairGenControl.ForbiddenKeypairGenControl) {
                throw new OperationException(BAD_CERT_TEMPLATE, "no public key is specified");
            }
            if (kg instanceof KeypairGenControl.RSAKeypairGenControl) {
                KeypairGenControl.RSAKeypairGenControl tkg = (KeypairGenControl.RSAKeypairGenControl) kg;
                int keysize = tkg.getKeysize();
                if (keysize > 4096) {
                    throw new OperationException(BAD_CERT_TEMPLATE, "keysize too large");
                }
                BigInteger publicExponent = tkg.getPublicExponent();
                KeyPair kp = KeyUtil.generateRSAKeypair(keysize, publicExponent, random);
                java.security.interfaces.RSAPublicKey rsaPubKey = (java.security.interfaces.RSAPublicKey) kp.getPublic();
                grantedPublicKeyInfo = new SubjectPublicKeyInfo(tkg.getKeyAlgorithm(), new RSAPublicKey(rsaPubKey.getModulus(), rsaPubKey.getPublicExponent()));
                /*
           * RSA private keys are BER-encoded according to PKCS #1’s RSAPrivateKey ASN.1 type.
           *
           * RSAPrivateKey ::= SEQUENCE {
           *   version           Version,
           *   modulus           INTEGER,  -- n
           *   publicExponent    INTEGER,  -- e
           *   privateExponent   INTEGER,  -- d
           *   prime1            INTEGER,  -- p
           *   prime2            INTEGER,  -- q
           *   exponent1         INTEGER,  -- d mod (p-1)
           *   exponent2         INTEGER,  -- d mod (q-1)
           *   coefficient       INTEGER,  -- (inverse of q) mod p
           *   otherPrimeInfos   OtherPrimeInfos OPTIONAL.
           * }
           */
                RSAPrivateCrtKey priv = (RSAPrivateCrtKey) kp.getPrivate();
                privateKey = new PrivateKeyInfo(tkg.getKeyAlgorithm(), new RSAPrivateKey(priv.getModulus(), priv.getPublicExponent(), priv.getPrivateExponent(), priv.getPrimeP(), priv.getPrimeQ(), priv.getPrimeExponentP(), priv.getPrimeExponentQ(), priv.getCrtCoefficient()));
            } else if (kg instanceof KeypairGenControl.ECKeypairGenControl) {
                KeypairGenControl.ECKeypairGenControl tkg = (KeypairGenControl.ECKeypairGenControl) kg;
                ASN1ObjectIdentifier curveOid = tkg.getCurveOid();
                KeyPair kp = KeyUtil.generateECKeypair(curveOid, random);
                ECPublicKey pub = (ECPublicKey) kp.getPublic();
                int orderBitLength = pub.getParams().getOrder().bitLength();
                byte[] keyData = KeyUtil.getUncompressedEncodedECPoint(pub.getW(), orderBitLength);
                grantedPublicKeyInfo = new SubjectPublicKeyInfo(tkg.getKeyAlgorithm(), keyData);
                /*
           * ECPrivateKey ::= SEQUENCE {
           *   Version INTEGER { ecPrivkeyVer1(1) }
           *                   (ecPrivkeyVer1),
           *   privateKey      OCTET STRING,
           *   parameters [0]  Parameters OPTIONAL,
           *   publicKey  [1]  BIT STRING OPTIONAL
           * }
           *
           * Since the EC domain parameters are placed in the PKCS #8’s privateKeyAlgorithm field,
           * the optional parameters field in an ECPrivateKey must be omitted. A Cryptoki
           * application must be able to unwrap an ECPrivateKey that contains the optional publicKey
           * field; however, what is done with this publicKey field is outside the scope of
           * Cryptoki.
           */
                ECPrivateKey priv = (ECPrivateKey) kp.getPrivate();
                privateKey = new PrivateKeyInfo(tkg.getKeyAlgorithm(), new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, priv.getS()));
            } else if (kg instanceof KeypairGenControl.DSAKeypairGenControl) {
                KeypairGenControl.DSAKeypairGenControl tkg = (KeypairGenControl.DSAKeypairGenControl) kg;
                KeyPair kp = KeyUtil.generateDSAKeypair(tkg.getParameterSpec(), random);
                grantedPublicKeyInfo = new SubjectPublicKeyInfo(tkg.getKeyAlgorithm(), new ASN1Integer(((DSAPublicKey) kp.getPublic()).getY()));
                // DSA private keys are represented as BER-encoded ASN.1 type INTEGER.
                DSAPrivateKey priv = (DSAPrivateKey) kp.getPrivate();
                privateKey = new PrivateKeyInfo(grantedPublicKeyInfo.getAlgorithm(), new ASN1Integer(priv.getX()));
            } else if (kg instanceof KeypairGenControl.EDDSAKeypairGenControl) {
                KeypairGenControl.EDDSAKeypairGenControl tkg = (KeypairGenControl.EDDSAKeypairGenControl) kg;
                KeyPair kp = KeyUtil.generateEdECKeypair(tkg.getKeyAlgorithm().getAlgorithm(), random);
                grantedPublicKeyInfo = KeyUtil.createSubjectPublicKeyInfo(kp.getPublic());
                // make sure that the algorithm match
                if (!grantedPublicKeyInfo.getAlgorithm().equals(tkg.getKeyAlgorithm())) {
                    throw new OperationException(SYSTEM_FAILURE, "invalid SubjectPublicKeyInfo.algorithm");
                }
                privateKey = PrivateKeyInfo.getInstance(kp.getPrivate().getEncoded());
            } else {
                throw new RuntimeCryptoException("unknown KeyPairGenControl " + kg);
            }
        } catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | NoSuchProviderException | InvalidKeyException | IOException ex) {
            throw new OperationException(SYSTEM_FAILURE, ex);
        }
    } else {
        // show not reach here
        throw new OperationException(BAD_CERT_TEMPLATE, "no public key is specified  genkey");
    }
    // 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;
}
Also used : Certprofile(org.xipki.ca.api.profile.Certprofile) NameId(org.xipki.ca.api.NameId) X500Name(org.bouncycastle.asn1.x500.X500Name) SubjectPublicKeyInfo(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo) KeypairGenControl(org.xipki.ca.api.profile.KeypairGenControl) ValidityMode(org.xipki.ca.api.mgmt.ValidityMode) RSAPublicKey(org.bouncycastle.asn1.pkcs.RSAPublicKey) CertprofileException(org.xipki.ca.api.profile.CertprofileException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) GrantedCertTemplate(org.xipki.ca.server.X509Ca.GrantedCertTemplate) OperationException(org.xipki.ca.api.OperationException) ASN1Sequence(org.bouncycastle.asn1.ASN1Sequence) BadCertTemplateException(org.xipki.ca.api.BadCertTemplateException) BigInteger(java.math.BigInteger) RSAPrivateKey(org.bouncycastle.asn1.pkcs.RSAPrivateKey) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier) java.security(java.security) RDN(org.bouncycastle.asn1.x500.RDN) java.security.interfaces(java.security.interfaces) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) NotAfterMode(org.xipki.ca.api.profile.NotAfterMode) Date(java.util.Date) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) BigInteger(java.math.BigInteger) Validity(org.xipki.util.Validity) RuntimeCryptoException(org.bouncycastle.crypto.RuntimeCryptoException) ConcurrentContentSigner(org.xipki.security.ConcurrentContentSigner) CertStore(org.xipki.ca.server.db.CertStore) PrivateKeyInfo(org.bouncycastle.asn1.pkcs.PrivateKeyInfo)

Example 7 with RSAPublicKey

use of com.github.zhenwei.core.asn1.pkcs.RSAPublicKey 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;
}
Also used : Certprofile(org.xipki.ca.api.profile.Certprofile) NameId(org.xipki.ca.api.NameId) X500Name(org.bouncycastle.asn1.x500.X500Name) ASN1BitString(org.bouncycastle.asn1.ASN1BitString) SubjectPublicKeyInfo(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo) ASN1BitString(org.bouncycastle.asn1.ASN1BitString) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier) KeypairGenControl(org.xipki.ca.api.profile.KeypairGenControl) XiSecurityException(org.xipki.security.XiSecurityException) ValidityMode(org.xipki.ca.api.mgmt.ValidityMode) RSAPublicKey(org.bouncycastle.asn1.pkcs.RSAPublicKey) CertprofileException(org.xipki.ca.api.profile.CertprofileException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) GrantedCertTemplate(org.xipki.ca.server.X509Ca.GrantedCertTemplate) RDN(org.bouncycastle.asn1.x500.RDN) OperationException(org.xipki.ca.api.OperationException) ECPrivateKey(org.bouncycastle.asn1.sec.ECPrivateKey) KeypairGenerator(org.xipki.security.KeypairGenerator) IOException(java.io.IOException) NotAfterMode(org.xipki.ca.api.profile.NotAfterMode) Date(java.util.Date) ASN1Integer(org.bouncycastle.asn1.ASN1Integer) BigInteger(java.math.BigInteger) Validity(org.xipki.util.Validity) ConcurrentContentSigner(org.xipki.security.ConcurrentContentSigner) ASN1Sequence(org.bouncycastle.asn1.ASN1Sequence) BadCertTemplateException(org.xipki.ca.api.BadCertTemplateException) BigInteger(java.math.BigInteger) RSAPrivateKey(org.bouncycastle.asn1.pkcs.RSAPrivateKey) CertStore(org.xipki.ca.server.db.CertStore) PrivateKeyInfo(org.bouncycastle.asn1.pkcs.PrivateKeyInfo) ASN1ObjectIdentifier(org.bouncycastle.asn1.ASN1ObjectIdentifier)

Example 8 with RSAPublicKey

use of com.github.zhenwei.core.asn1.pkcs.RSAPublicKey in project xipki by xipki.

the class P12KeyGenerator method genRSAKeypair.

// method generateSecretKey
private KeyPairWithSubjectPublicKeyInfo genRSAKeypair(int keysize, BigInteger publicExponent, SecureRandom random) throws Exception {
    KeyPair kp = KeyUtil.generateRSAKeypair(keysize, publicExponent, random);
    java.security.interfaces.RSAPublicKey rsaPubKey = (java.security.interfaces.RSAPublicKey) kp.getPublic();
    SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKey(rsaPubKey.getModulus(), rsaPubKey.getPublicExponent()));
    return new KeyPairWithSubjectPublicKeyInfo(kp, spki);
}
Also used : org.xipki.security(org.xipki.security) java.security(java.security) RSAPublicKey(org.bouncycastle.asn1.pkcs.RSAPublicKey) SubjectPublicKeyInfo(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo) AlgorithmIdentifier(org.bouncycastle.asn1.x509.AlgorithmIdentifier)

Example 9 with RSAPublicKey

use of com.github.zhenwei.core.asn1.pkcs.RSAPublicKey in project LinLong-Java by zhenwei1108.

the class SubjectPublicKeyInfoFactory method createSubjectPublicKeyInfo.

/**
 * Create a SubjectPublicKeyInfo public key.
 *
 * @param publicKey the key to be encoded into the info object.
 * @return a SubjectPublicKeyInfo representing the key.
 * @throws IOException on an error encoding the key
 */
public static SubjectPublicKeyInfo createSubjectPublicKeyInfo(AsymmetricKeyParameter publicKey) throws IOException {
    if (publicKey instanceof RSAKeyParameters) {
        RSAKeyParameters pub = (RSAKeyParameters) publicKey;
        return new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKey(pub.getModulus(), pub.getExponent()));
    } else if (publicKey instanceof DSAPublicKeyParameters) {
        DSAPublicKeyParameters pub = (DSAPublicKeyParameters) publicKey;
        DSAParameter params = null;
        DSAParameters dsaParams = pub.getParameters();
        if (dsaParams != null) {
            params = new DSAParameter(dsaParams.getP(), dsaParams.getQ(), dsaParams.getG());
        }
        return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, params), new ASN1Integer(pub.getY()));
    } else if (publicKey instanceof ECPublicKeyParameters) {
        ECPublicKeyParameters pub = (ECPublicKeyParameters) publicKey;
        ECDomainParameters domainParams = pub.getParameters();
        ASN1Encodable params;
        if (domainParams == null) {
            // Implicitly CA
            params = new X962Parameters(DERNull.INSTANCE);
        } else if (domainParams instanceof ECGOST3410Parameters) {
            ECGOST3410Parameters gostParams = (ECGOST3410Parameters) domainParams;
            BigInteger bX = pub.getQ().getAffineXCoord().toBigInteger();
            BigInteger bY = pub.getQ().getAffineYCoord().toBigInteger();
            params = new GOST3410PublicKeyAlgParameters(gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet());
            int encKeySize;
            int offset;
            ASN1ObjectIdentifier algIdentifier;
            if (cryptoProOids.contains(gostParams.getPublicKeyParamSet())) {
                encKeySize = 64;
                offset = 32;
                algIdentifier = CryptoProObjectIdentifiers.gostR3410_2001;
            } else {
                boolean is512 = (bX.bitLength() > 256);
                if (is512) {
                    encKeySize = 128;
                    offset = 64;
                    algIdentifier = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512;
                } else {
                    encKeySize = 64;
                    offset = 32;
                    algIdentifier = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256;
                }
            }
            byte[] encKey = new byte[encKeySize];
            extractBytes(encKey, encKeySize / 2, 0, bX);
            extractBytes(encKey, encKeySize / 2, offset, bY);
            try {
                return new SubjectPublicKeyInfo(new AlgorithmIdentifier(algIdentifier, params), new DEROctetString(encKey));
            } catch (IOException e) {
                return null;
            }
        } else if (domainParams instanceof ECNamedDomainParameters) {
            params = new X962Parameters(((ECNamedDomainParameters) domainParams).getName());
        } else {
            X9ECParameters ecP = new X9ECParameters(domainParams.getCurve(), // TODO Support point compression
            new X9ECPoint(domainParams.getG(), false), domainParams.getN(), domainParams.getH(), domainParams.getSeed());
            params = new X962Parameters(ecP);
        }
        // TODO Support point compression
        byte[] pubKeyOctets = pub.getQ().getEncoded(false);
        return new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), pubKeyOctets);
    } else if (publicKey instanceof X448PublicKeyParameters) {
        X448PublicKeyParameters key = (X448PublicKeyParameters) publicKey;
        return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X448), key.getEncoded());
    } else if (publicKey instanceof X25519PublicKeyParameters) {
        X25519PublicKeyParameters key = (X25519PublicKeyParameters) publicKey;
        return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), key.getEncoded());
    } else if (publicKey instanceof Ed448PublicKeyParameters) {
        Ed448PublicKeyParameters key = (Ed448PublicKeyParameters) publicKey;
        return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448), key.getEncoded());
    } else if (publicKey instanceof Ed25519PublicKeyParameters) {
        Ed25519PublicKeyParameters key = (Ed25519PublicKeyParameters) publicKey;
        return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), key.getEncoded());
    } else {
        throw new IOException("key parameters not recognized");
    }
}
Also used : ECDomainParameters(com.github.zhenwei.core.crypto.params.ECDomainParameters) X9ECParameters(com.github.zhenwei.core.asn1.x9.X9ECParameters) ECGOST3410Parameters(com.github.zhenwei.core.crypto.params.ECGOST3410Parameters) GOST3410PublicKeyAlgParameters(com.github.zhenwei.core.asn1.cryptopro.GOST3410PublicKeyAlgParameters) SubjectPublicKeyInfo(com.github.zhenwei.core.asn1.x509.SubjectPublicKeyInfo) ECPublicKeyParameters(com.github.zhenwei.core.crypto.params.ECPublicKeyParameters) RSAKeyParameters(com.github.zhenwei.core.crypto.params.RSAKeyParameters) DEROctetString(com.github.zhenwei.core.asn1.DEROctetString) AlgorithmIdentifier(com.github.zhenwei.core.asn1.x509.AlgorithmIdentifier) Ed448PublicKeyParameters(com.github.zhenwei.core.crypto.params.Ed448PublicKeyParameters) X962Parameters(com.github.zhenwei.core.asn1.x9.X962Parameters) RSAPublicKey(com.github.zhenwei.core.asn1.pkcs.RSAPublicKey) X25519PublicKeyParameters(com.github.zhenwei.core.crypto.params.X25519PublicKeyParameters) Ed25519PublicKeyParameters(com.github.zhenwei.core.crypto.params.Ed25519PublicKeyParameters) DSAParameter(com.github.zhenwei.core.asn1.x509.DSAParameter) ASN1Encodable(com.github.zhenwei.core.asn1.ASN1Encodable) DSAPublicKeyParameters(com.github.zhenwei.core.crypto.params.DSAPublicKeyParameters) ECNamedDomainParameters(com.github.zhenwei.core.crypto.params.ECNamedDomainParameters) X448PublicKeyParameters(com.github.zhenwei.core.crypto.params.X448PublicKeyParameters) ASN1Integer(com.github.zhenwei.core.asn1.ASN1Integer) IOException(java.io.IOException) X9ECPoint(com.github.zhenwei.core.asn1.x9.X9ECPoint) BigInteger(java.math.BigInteger) DSAParameters(com.github.zhenwei.core.crypto.params.DSAParameters) ASN1ObjectIdentifier(com.github.zhenwei.core.asn1.ASN1ObjectIdentifier)

Aggregations

RSAPublicKey (org.bouncycastle.asn1.pkcs.RSAPublicKey)5 BigInteger (java.math.BigInteger)4 ASN1ObjectIdentifier (org.bouncycastle.asn1.ASN1ObjectIdentifier)4 AlgorithmIdentifier (org.bouncycastle.asn1.x509.AlgorithmIdentifier)4 SubjectPublicKeyInfo (org.bouncycastle.asn1.x509.SubjectPublicKeyInfo)4 ASN1Integer (com.github.zhenwei.core.asn1.ASN1Integer)3 ASN1Integer (org.bouncycastle.asn1.ASN1Integer)3 ASN1EncodableVector (com.github.zhenwei.core.asn1.ASN1EncodableVector)2 ASN1ObjectIdentifier (com.github.zhenwei.core.asn1.ASN1ObjectIdentifier)2 DERSequence (com.github.zhenwei.core.asn1.DERSequence)2 IOException (java.io.IOException)2 java.security (java.security)2 InvalidKeySpecException (java.security.spec.InvalidKeySpecException)2 Date (java.util.Date)2 ASN1Sequence (org.bouncycastle.asn1.ASN1Sequence)2 PrivateKeyInfo (org.bouncycastle.asn1.pkcs.PrivateKeyInfo)2 RSAPrivateKey (org.bouncycastle.asn1.pkcs.RSAPrivateKey)2 RDN (org.bouncycastle.asn1.x500.RDN)2 X500Name (org.bouncycastle.asn1.x500.X500Name)2 BadCertTemplateException (org.xipki.ca.api.BadCertTemplateException)2