Ejemplo n.º 1
0
        public static AsymmetricKeyParameter CreateKey(
            SubjectPublicKeyInfo keyInfo)
        {
            AlgorithmIdentifier algID  = keyInfo.AlgorithmID;
            DerObjectIdentifier algOid = algID.Algorithm;

            // TODO See RSAUtil.isRsaOid in Java build
            if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption) ||
                algOid.Equals(X509ObjectIdentifiers.IdEARsa) ||
                algOid.Equals(PkcsObjectIdentifiers.IdRsassaPss) ||
                algOid.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
            {
                RsaPublicKeyStructure pubKey = RsaPublicKeyStructure.GetInstance(
                    keyInfo.ParsePublicKey());

                return(new RsaKeyParameters(false, pubKey.Modulus, pubKey.PublicExponent));
            }
            else if (algOid.Equals(X9ObjectIdentifiers.DHPublicNumber))
            {
                Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object());

                DHPublicKey dhPublicKey = DHPublicKey.GetInstance(keyInfo.ParsePublicKey());

                BigInteger y = dhPublicKey.Y.Value;

                if (IsPkcsDHParam(seq))
                {
                    return(ReadPkcsDHParam(algOid, y, seq));
                }

                DHDomainParameters dhParams = DHDomainParameters.GetInstance(seq);

                BigInteger p = dhParams.P.Value;
                BigInteger g = dhParams.G.Value;
                BigInteger q = dhParams.Q.Value;

                BigInteger j = null;
                if (dhParams.J != null)
                {
                    j = dhParams.J.Value;
                }

                DHValidationParameters validation        = null;
                DHValidationParms      dhValidationParms = dhParams.ValidationParms;
                if (dhValidationParms != null)
                {
                    byte[]     seed        = dhValidationParms.Seed.GetBytes();
                    BigInteger pgenCounter = dhValidationParms.PgenCounter.Value;

                    // TODO Check pgenCounter size?

                    validation = new DHValidationParameters(seed, pgenCounter.IntValue);
                }

                return(new DHPublicKeyParameters(y, new DHParameters(p, g, q, j, validation)));
            }
            else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
            {
                Asn1Sequence seq = Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object());

                DerInteger derY = (DerInteger)keyInfo.ParsePublicKey();

                return(ReadPkcsDHParam(algOid, derY.Value, seq));
            }
            else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
            {
                ElGamalParameter para = new ElGamalParameter(
                    Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
                DerInteger derY = (DerInteger)keyInfo.ParsePublicKey();

                return(new ElGamalPublicKeyParameters(
                           derY.Value,
                           new ElGamalParameters(para.P, para.G)));
            }
            else if (algOid.Equals(X9ObjectIdentifiers.IdDsa) ||
                     algOid.Equals(OiwObjectIdentifiers.DsaWithSha1))
            {
                DerInteger    derY = (DerInteger)keyInfo.ParsePublicKey();
                Asn1Encodable ae   = algID.Parameters;

                DsaParameters parameters = null;
                if (ae != null)
                {
                    DsaParameter para = DsaParameter.GetInstance(ae.ToAsn1Object());
                    parameters = new DsaParameters(para.P, para.Q, para.G);
                }

                return(new DsaPublicKeyParameters(derY.Value, parameters));
            }
            else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey))
            {
                X962Parameters para = X962Parameters.GetInstance(algID.Parameters.ToAsn1Object());

                X9ECParameters x9;
                if (para.IsNamedCurve)
                {
                    x9 = ECKeyPairGenerator.FindECCurveByOid((DerObjectIdentifier)para.Parameters);
                }
                else
                {
                    x9 = new X9ECParameters((Asn1Sequence)para.Parameters);
                }

                Asn1OctetString key  = new DerOctetString(keyInfo.PublicKeyData.GetBytes());
                X9ECPoint       derQ = new X9ECPoint(x9.Curve, key);
                ECPoint         q    = derQ.Point;

                if (para.IsNamedCurve)
                {
                    return(new ECPublicKeyParameters("EC", q, (DerObjectIdentifier)para.Parameters));
                }

                ECDomainParameters dParams = new ECDomainParameters(x9);
                return(new ECPublicKeyParameters(q, dParams));
            }
            else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
            {
                Gost3410PublicKeyAlgParameters gostParams        = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters);
                DerObjectIdentifier            publicKeyParamSet = gostParams.PublicKeyParamSet;

                X9ECParameters ecP = ECGost3410NamedCurves.GetByOidX9(publicKeyParamSet);
                if (ecP == null)
                {
                    return(null);
                }

                Asn1OctetString key;
                try
                {
                    key = (Asn1OctetString)keyInfo.ParsePublicKey();
                }
                catch (IOException e)
                {
                    throw new ArgumentException("error recovering GOST3410_2001 public key", e);
                }

                int fieldSize = 32;
                int keySize   = 2 * fieldSize;

                byte[] keyEnc = key.GetOctets();
                if (keyEnc.Length != keySize)
                {
                    throw new ArgumentException("invalid length for GOST3410_2001 public key");
                }

                byte[] x9Encoding = new byte[1 + keySize];
                x9Encoding[0] = 0x04;
                for (int i = 1; i <= fieldSize; ++i)
                {
                    x9Encoding[i]             = keyEnc[fieldSize - i];
                    x9Encoding[i + fieldSize] = keyEnc[keySize - i];
                }

                ECPoint q = ecP.Curve.DecodePoint(x9Encoding);

                return(new ECPublicKeyParameters("ECGOST3410", q, publicKeyParamSet));
            }
            else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
            {
                Gost3410PublicKeyAlgParameters algParams = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters);

                Asn1OctetString key;
                try
                {
                    key = (Asn1OctetString)keyInfo.ParsePublicKey();
                }
                catch (IOException e)
                {
                    throw new ArgumentException("error recovering GOST3410_94 public key", e);
                }

                byte[] keyBytes = Arrays.Reverse(key.GetOctets()); // was little endian

                BigInteger y = new BigInteger(1, keyBytes);

                return(new Gost3410PublicKeyParameters(y, algParams.PublicKeyParamSet));
            }
            else if (algOid.Equals(EdECObjectIdentifiers.id_X25519))
            {
                return(new X25519PublicKeyParameters(GetRawKey(keyInfo)));
            }
            else if (algOid.Equals(EdECObjectIdentifiers.id_X448))
            {
                return(new X448PublicKeyParameters(GetRawKey(keyInfo)));
            }
            else if (algOid.Equals(EdECObjectIdentifiers.id_Ed25519))
            {
                return(new Ed25519PublicKeyParameters(GetRawKey(keyInfo)));
            }
            else if (algOid.Equals(EdECObjectIdentifiers.id_Ed448))
            {
                return(new Ed448PublicKeyParameters(GetRawKey(keyInfo)));
            }
            else if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256) ||
                     algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512))
            {
                Gost3410PublicKeyAlgParameters gostParams        = Gost3410PublicKeyAlgParameters.GetInstance(algID.Parameters);
                DerObjectIdentifier            publicKeyParamSet = gostParams.PublicKeyParamSet;

                ECGost3410Parameters ecDomainParameters = new ECGost3410Parameters(
                    new ECNamedDomainParameters(publicKeyParamSet, ECGost3410NamedCurves.GetByOidX9(publicKeyParamSet)),
                    publicKeyParamSet,
                    gostParams.DigestParamSet,
                    gostParams.EncryptionParamSet);

                Asn1OctetString key;
                try
                {
                    key = (Asn1OctetString)keyInfo.ParsePublicKey();
                }
                catch (IOException e)
                {
                    throw new ArgumentException("error recovering GOST3410_2012 public key", e);
                }

                int fieldSize = 32;
                if (algOid.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512))
                {
                    fieldSize = 64;
                }
                int keySize = 2 * fieldSize;

                byte[] keyEnc = key.GetOctets();
                if (keyEnc.Length != keySize)
                {
                    throw new ArgumentException("invalid length for GOST3410_2012 public key");
                }

                byte[] x9Encoding = new byte[1 + keySize];
                x9Encoding[0] = 0x04;
                for (int i = 1; i <= fieldSize; ++i)
                {
                    x9Encoding[i]             = keyEnc[fieldSize - i];
                    x9Encoding[i + fieldSize] = keyEnc[keySize - i];
                }

                ECPoint q = ecDomainParameters.Curve.DecodePoint(x9Encoding);

                return(new ECPublicKeyParameters(q, ecDomainParameters));
            }
            else
            {
                throw new SecurityUtilityException("algorithm identifier in public key not recognised: " + algOid);
            }
        }
Ejemplo n.º 2
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log,
            ExecutionContext context)
        {
            log.LogInformation("Certificate trigger function processed a request.");

            try
            {
                await ReadAppSettings(context, log);

                string requestBody          = await new StreamReader(req.Body).ReadToEndAsync();
                Certificate_Request request = JsonConvert.DeserializeObject <Certificate_Request>(requestBody);

                // Validate payload
                if (string.IsNullOrEmpty(request.RegistrationId) || string.IsNullOrEmpty(request.Csr))
                {
                    return(new BadRequestResult());
                }

                // Check if the device is authorized to request a certificate
                bool isAuthorized = CheckIfAuthorized(request.RegistrationId);

                if (isAuthorized)
                {
                    log.LogInformation($"{request.RegistrationId} is authorized.");

                    Pkcs10CertificationRequest decodedCsr = null;
                    RsaKeyParameters           publicKey  = null;
                    CertificationRequestInfo   info       = null;

                    // Get the signing certificate from a location
                    X509Certificate serverCertificate = ReadCertificate(cert, location, log);

                    if (serverCertificate == null)
                    {
                        throw new System.Exception("ReadCertificate() was unable to retrieve the signing certificate.");
                    }

                    // Get signing cert private key from a location.
                    AsymmetricKeyParameter serverPrivateKey = ReadPrivateKey(key, location, log);

                    if (serverPrivateKey == null)
                    {
                        throw new System.Exception("ReadPrivateKey() was unable to retrieve the private key.");
                    }

                    byte[] csr = Convert.FromBase64String(request.Csr);

                    // Decode DER
                    decodedCsr = new Pkcs10CertificationRequest(csr);
                    info       = decodedCsr.GetCertificationRequestInfo();
                    SubjectPublicKeyInfo publicKeyInfo = info.SubjectPublicKeyInfo;

                    RsaPublicKeyStructure publicKeyStructure = RsaPublicKeyStructure.GetInstance(publicKeyInfo.ParsePublicKey());

                    publicKey = new RsaKeyParameters(false, publicKeyStructure.Modulus, publicKeyStructure.PublicExponent);

                    bool certIsOK = decodedCsr.Verify(publicKey);

                    // Create the device certificate
                    X509V3CertificateGenerator generator = new X509V3CertificateGenerator();

                    generator.SetSerialNumber(BigInteger.ProbablePrime(120, new Random()));
                    generator.SetIssuerDN(serverCertificate.SubjectDN);
                    generator.SetNotBefore(DateTime.Now);
                    generator.SetNotAfter(DateTime.Now.AddYears(certificateLifespanInYears));
                    generator.SetSubjectDN(info.Subject);
                    generator.SetPublicKey(publicKey);
                    generator.SetSignatureAlgorithm("SHA512withRSA");
                    generator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(serverCertificate));
                    generator.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(publicKey));

                    // Generate the device certificate
                    var deviceCert = generator.Generate(serverPrivateKey);

                    // Convert to DER
                    byte[] encoded = deviceCert.GetEncoded();

                    // Convert byte array to Base64 string
                    string encodedString = Convert.ToBase64String(encoded);

                    Certificate_Response responseMessage = new Certificate_Response
                    {
                        Certificate = encodedString
                    };

                    log.LogInformation($"Certificate issued for: {info.Subject}");

                    return(new OkObjectResult(responseMessage));
                }
                else
                {
                    log.LogError($"{request.RegistrationId} is NOT authorized.");

                    return(new UnauthorizedResult());
                }
            }
            catch (Exception ex)
            {
                log.LogInformation(ex.Message);
            }

            return(new BadRequestResult());
        }