예제 #1
0
        /// <summary>
        /// Populate the fields by the decoding DER data from the Content.
        /// </summary>
        ///
        private void decode()
        {
            DerNode parsedNode = net.named_data.jndn.encoding.der.DerNode.parse(getContent().buf());

            // We need to ensure that there are:
            //   validity (notBefore, notAfter)
            //   subject list
            //   public key
            //   (optional) extension list

            IList rootChildren = parsedNode.getChildren();
            // 1st: validity info
            IList validityChildren = net.named_data.jndn.encoding.der.DerNode.getSequence(rootChildren, 0)
                                     .getChildren();

            notBefore_ = ((Double)((net.named_data.jndn.encoding.der.DerNode.DerGeneralizedTime)validityChildren[0]).toVal());
            notAfter_  = ((Double)((net.named_data.jndn.encoding.der.DerNode.DerGeneralizedTime)validityChildren[1]).toVal());

            // 2nd: subjectList
            IList subjectChildren = net.named_data.jndn.encoding.der.DerNode.getSequence(rootChildren, 1)
                                    .getChildren();

            for (int i = 0; i < subjectChildren.Count; ++i)
            {
                net.named_data.jndn.encoding.der.DerNode.DerSequence sd = net.named_data.jndn.encoding.der.DerNode.getSequence(subjectChildren, i);
                IList  descriptionChildren = sd.getChildren();
                String oidStr = (String)((DerNode)descriptionChildren[0])
                                .toVal();
                String value_ren = ""
                                   + ((Blob)((DerNode)descriptionChildren[1]).toVal());

                addSubjectDescription(new CertificateSubjectDescription(oidStr,
                                                                        value_ren));
            }

            // 3rd: public key
            Blob publicKeyInfo = ((DerNode)rootChildren[2]).encode();

            try {
                key_ = new PublicKey(publicKeyInfo);
            } catch (UnrecognizedKeyFormatException ex) {
                throw new DerDecodingException(ex.Message);
            }

            if (rootChildren.Count > 3)
            {
                IList extensionChildren = net.named_data.jndn.encoding.der.DerNode.getSequence(rootChildren, 3)
                                          .getChildren();
                for (int i_0 = 0; i_0 < extensionChildren.Count; ++i_0)
                {
                    net.named_data.jndn.encoding.der.DerNode.DerSequence extInfo = net.named_data.jndn.encoding.der.DerNode.getSequence(extensionChildren, i_0);

                    IList  children   = extInfo.getChildren();
                    String oidStr_1   = (String)((DerNode)children[0]).toVal();
                    bool   isCritical = (bool)(((Boolean)((net.named_data.jndn.encoding.der.DerNode.DerBoolean)children[1]).toVal()));
                    Blob   value_2    = (Blob)((DerNode)children[2]).toVal();
                    addExtension(new CertificateExtension(oidStr_1, isCritical, value_2));
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Encode the contents of the certificate in DER format and set the Content
        /// and MetaInfo fields.
        /// </summary>
        ///
        public void encode()
        {
            DerNode root = toDer();

            setContent(root.encode());
            getMetaInfo().setType(net.named_data.jndn.ContentType.KEY);
        }
예제 #3
0
        /// <summary>
        /// Derive a new encrypt key from the given decrypt key value.
        /// </summary>
        ///
        /// <param name="keyBits"></param>
        /// <returns>The new encrypt key (DER-encoded public key).</returns>
        public static EncryptKey deriveEncryptKey(Blob keyBits)
        {
            // Decode the PKCS #8 private key. (We don't use RSAPrivateCrtKey because
            // the Android library doesn't have an easy way to decode into it.)
            DerNode parsedNode          = net.named_data.jndn.encoding.der.DerNode.parse(keyBits.buf(), 0);
            IList   pkcs8Children       = parsedNode.getChildren();
            IList   algorithmIdChildren = net.named_data.jndn.encoding.der.DerNode.getSequence(pkcs8Children, 1)
                                          .getChildren();
            String oidString = ((DerNode.DerOid)algorithmIdChildren[0])
                               .toVal().toString();
            Blob rsaPrivateKeyDer = ((DerNode)pkcs8Children[2]).getPayload();

            String RSA_ENCRYPTION_OID = "1.2.840.113549.1.1.1";

            if (!oidString.equals(RSA_ENCRYPTION_OID))
            {
                throw new DerDecodingException(
                          "The PKCS #8 private key is not RSA_ENCRYPTION");
            }

            // Decode the PKCS #1 RSAPrivateKey.
            parsedNode = net.named_data.jndn.encoding.der.DerNode.parse(rsaPrivateKeyDer.buf(), 0);
            IList rsaPrivateKeyChildren = parsedNode.getChildren();
            Blob  modulus        = ((DerNode)rsaPrivateKeyChildren[1]).getPayload();
            Blob  publicExponent = ((DerNode)rsaPrivateKeyChildren[2])
                                   .getPayload();

            System.SecurityPublicKey publicKey = keyFactory_
                                                 .generatePublic(new RSAPublicKeySpec(new Int64(modulus
                                                                                                .getImmutableArray()), new Int64(publicExponent
                                                                                                                                 .getImmutableArray())));

            return(new EncryptKey(new Blob(publicKey.getEncoded(), false)));
        }
예제 #4
0
        /// <summary>
        /// Load the unencrypted private key from a buffer with the PKCS #1 encoding.
        /// This replaces any existing private key in this object.
        /// </summary>
        ///
        /// <param name="encoding">The byte buffer with the private key encoding.</param>
        /// <param name="keyType"></param>
        /// <exception cref="TpmPrivateKey.Error">for errors decoding the key.</exception>
        public void loadPkcs1(ByteBuffer encoding, KeyType keyType)
        {
            if (keyType == null)
            {
                // Try to determine the key type.
                try {
                    DerNode parsedNode = net.named_data.jndn.encoding.der.DerNode.parse(encoding);
                    IList   children   = parsedNode.getChildren();

                    // An RsaPrivateKey has integer version 0 and 8 integers.
                    if (children.Count == 9 &&
                        children[0]   is  DerNode.DerInteger &&
                        ((int)((DerNode.DerInteger)children[0])
                         .toVal()) == 0 &&
                        children[1]   is  DerNode.DerInteger &&
                        children[2]   is  DerNode.DerInteger &&
                        children[3]   is  DerNode.DerInteger &&
                        children[4]   is  DerNode.DerInteger &&
                        children[5]   is  DerNode.DerInteger &&
                        children[6]   is  DerNode.DerInteger &&
                        children[7]   is  DerNode.DerInteger &&
                        children[8]   is  DerNode.DerInteger)
                    {
                        keyType = net.named_data.jndn.security.KeyType.RSA;
                    }
                    else
                    {
                        // Assume it is an EC key. Try decoding it below.
                        keyType = net.named_data.jndn.security.KeyType.EC;
                    }
                } catch (DerDecodingException ex) {
                    // Assume it is an EC key. Try decoding it below.
                    keyType = net.named_data.jndn.security.KeyType.EC;
                }
            }

            // Java can't decode a PKCS #1 private key, so make a PKCS #8 private key
            // and decode that.
            Blob pkcs8;

            if (keyType == net.named_data.jndn.security.KeyType.EC)
            {
                throw new TpmPrivateKey.Error(
                          "TODO: loadPkcs1 for EC is not implemented");
            }
            else if (keyType == net.named_data.jndn.security.KeyType.RSA)
            {
                pkcs8 = encodePkcs8PrivateKey(encoding,
                                              new OID(RSA_ENCRYPTION_OID), new DerNode.DerNull());
            }
            else
            {
                throw new TpmPrivateKey.Error("loadPkcs1: Unrecognized keyType: "
                                              + keyType);
            }

            loadPkcs8(pkcs8.buf(), keyType);
        }
예제 #5
0
        generatePrivate(KeySpec keySpec)
        {
            if (!(keySpec is PKCS8EncodedKeySpec))
            {
                throw new net.named_data.jndn.util.InvalidKeySpecException
                          ("RsaKeyFactory.generatePrivate expects a PKCS8EncodedKeySpec");
            }

            try {
                // Decode the PKCS #8 private key.
                var parsedNode          = DerNode.parse(new ByteBuffer(((PKCS8EncodedKeySpec)keySpec).KeyDer), 0);
                var pkcs8Children       = parsedNode.getChildren();
                var algorithmIdChildren = DerNode.getSequence(pkcs8Children, 1).getChildren();
                var oidString           = ((DerNode.DerOid)algorithmIdChildren[0]).toVal().ToString();
                var rsaPrivateKeyDer    = ((DerNode)pkcs8Children[2]).getPayload();

                if (oidString != RSA_ENCRYPTION_OID)
                {
                    throw new net.named_data.jndn.util.InvalidKeySpecException
                              ("The PKCS #8 private key is not RSA_ENCRYPTION");
                }

                // Decode the PKCS #1 RSAPrivateKey.
                parsedNode = DerNode.parse(rsaPrivateKeyDer.buf(), 0);
                var rsaPrivateKeyChildren = parsedNode.getChildren();

                // Copy the parameters.
                RSAParameters parameters = new RSAParameters();
                var           modulus    = getIntegerArrayWithoutLeadingZero(((DerNode)rsaPrivateKeyChildren[1]).getPayload());
                parameters.Modulus  = modulus;
                parameters.Exponent = getIntegerArrayWithoutLeadingZero(((DerNode)rsaPrivateKeyChildren[2]).getPayload());
                // RSAParameters expects the integer array of the correct length.
                parameters.D        = getIntegerArrayOfSize(((DerNode)rsaPrivateKeyChildren[3]).getPayload(), modulus.Length);
                parameters.P        = getIntegerArrayOfSize(((DerNode)rsaPrivateKeyChildren[4]).getPayload(), modulus.Length / 2);
                parameters.Q        = getIntegerArrayOfSize(((DerNode)rsaPrivateKeyChildren[5]).getPayload(), modulus.Length / 2);
                parameters.DP       = getIntegerArrayOfSize(((DerNode)rsaPrivateKeyChildren[6]).getPayload(), modulus.Length / 2);
                parameters.DQ       = getIntegerArrayOfSize(((DerNode)rsaPrivateKeyChildren[7]).getPayload(), modulus.Length / 2);
                parameters.InverseQ = getIntegerArrayOfSize(((DerNode)rsaPrivateKeyChildren[8]).getPayload(), modulus.Length / 2);

                return(new RsaSecurityPrivateKey(parameters));
            } catch (DerDecodingException ex) {
                throw new net.named_data.jndn.util.InvalidKeySpecException
                          ("RsaKeyFactory.generatePrivate error decoding the private key DER: " + ex);
            }
        }
예제 #6
0
        /// <summary>
        /// Encode the private key to a PKCS #8 private key. We do this explicitly here
        /// to avoid linking to extra OpenSSL libraries.
        /// </summary>
        ///
        /// <param name="privateKeyDer">The input private key DER.</param>
        /// <param name="oid">The OID of the privateKey.</param>
        /// <param name="parameters">The DerNode of the parameters for the OID.</param>
        /// <returns>The PKCS #8 private key DER.</returns>
        private static Blob encodePkcs8PrivateKey(ByteBuffer privateKeyDer,
                                                  OID oid, DerNode parameters)
        {
            try {
                net.named_data.jndn.encoding.der.DerNode.DerSequence algorithmIdentifier = new net.named_data.jndn.encoding.der.DerNode.DerSequence();
                algorithmIdentifier.addChild(new DerNode.DerOid(oid));
                algorithmIdentifier.addChild(parameters);

                net.named_data.jndn.encoding.der.DerNode.DerSequence result = new net.named_data.jndn.encoding.der.DerNode.DerSequence();
                result.addChild(new DerNode.DerInteger(0));
                result.addChild(algorithmIdentifier);
                result.addChild(new DerNode.DerOctetString(privateKeyDer));

                return(result.encode());
            } catch (DerEncodingException ex) {
                throw new TpmPrivateKey.Error(
                          "Error encoding PKCS #8 private key: " + ex);
            }
        }
예제 #7
0
        /// <summary>
        /// Get the encoded public key for this private key.
        /// </summary>
        ///
        /// <returns>The public key encoding Blob.</returns>
        /// <exception cref="TpmPrivateKey.Error">if no private key is loaded, or errorconverting to a public key.</exception>
        public Blob derivePublicKey()
        {
            if (keyType_ == net.named_data.jndn.security.KeyType.EC)
            {
                throw new TpmPrivateKey.Error(
                          "TODO: derivePublicKey for EC is not implemented");
            }
            else if (keyType_ == net.named_data.jndn.security.KeyType.RSA)
            {
                // Decode the PKCS #1 RSAPrivateKey. (We don't use RSAPrivateCrtKey because
                // the Android library doesn't have an easy way to decode into it.)
                IList rsaPrivateKeyChildren;
                try {
                    DerNode parsedNode = net.named_data.jndn.encoding.der.DerNode.parse(toPkcs1().buf(), 0);
                    rsaPrivateKeyChildren = parsedNode.getChildren();
                } catch (DerDecodingException ex) {
                    throw new TpmPrivateKey.Error("Error parsing RSA PKCS #1 key: "
                                                  + ex);
                }
                Blob modulus = ((DerNode)rsaPrivateKeyChildren[1])
                               .getPayload();
                Blob publicExponent = ((DerNode)rsaPrivateKeyChildren[2])
                                      .getPayload();

                try {
                    System.SecurityPublicKey publicKey = System.KeyFactory.getInstance(
                        "RSA").generatePublic(
                        new RSAPublicKeySpec((modulus
                                              .getImmutableArray()), (
                                                 publicExponent.getImmutableArray())));
                    return(new Blob(publicKey.getEncoded(), false));
                } catch (Exception ex_0) {
                    throw new TpmPrivateKey.Error("Error making RSA public key: "
                                                  + ex_0);
                }
            }
            else
            {
                throw new TpmPrivateKey.Error(
                          "derivePublicKey: The private key is not loaded");
            }
        }
예제 #8
0
        generatePublic(KeySpec keySpec)
        {
            if (!(keySpec is X509EncodedKeySpec))
            {
                throw new net.named_data.jndn.util.InvalidKeySpecException
                          ("RsaKeyFactory.generatePublic expects a X509EncodedKeySpec");
            }

            try {
                // Decode the X.509 public key.
                var parsedNode               = DerNode.parse(new ByteBuffer(((X509EncodedKeySpec)keySpec).KeyDer), 0);
                var rootChildren             = parsedNode.getChildren();
                var algorithmIdChildren      = DerNode.getSequence(rootChildren, 0).getChildren();
                var oidString                = ((DerNode.DerOid)algorithmIdChildren[0]).toVal().ToString();
                var rsaPublicKeyDerBitString = ((DerNode)rootChildren[1]).getPayload();

                if (oidString != RSA_ENCRYPTION_OID)
                {
                    throw new net.named_data.jndn.util.InvalidKeySpecException
                              ("The PKCS #8 private key is not RSA_ENCRYPTION");
                }

                // Decode the PKCS #1 RSAPublicKey.
                // Skip the leading 0 byte in the DER BitString.
                parsedNode = DerNode.parse(rsaPublicKeyDerBitString.buf(), 1);
                var rsaPublicKeyChildren = parsedNode.getChildren();

                // Copy the parameters.
                RSAParameters parameters = new RSAParameters();
                parameters.Modulus  = getIntegerArrayWithoutLeadingZero(((DerNode)rsaPublicKeyChildren[0]).getPayload());
                parameters.Exponent = getIntegerArrayWithoutLeadingZero(((DerNode)rsaPublicKeyChildren[1]).getPayload());

                return(new RsaSecurityPublicKey(parameters));
            } catch (DerDecodingException ex) {
                throw new net.named_data.jndn.util.InvalidKeySpecException
                          ("RsaKeyFactory.generatePublic error decoding the public key DER: " + ex);
            }
        }
예제 #9
0
        public void testExtension()
        {
            // Now add an extension.
            String name       = "/hello/kitty";
            int    trustClass = 0;
            int    trustLevel = 300;

            net.named_data.jndn.encoding.der.DerNode.DerSequence    extValueRoot       = new net.named_data.jndn.encoding.der.DerNode.DerSequence();
            net.named_data.jndn.encoding.der.DerNode.DerOctetString extValueName       = new net.named_data.jndn.encoding.der.DerNode.DerOctetString(new Blob(name).buf());
            net.named_data.jndn.encoding.der.DerNode.DerInteger     extValueTrustClass = new net.named_data.jndn.encoding.der.DerNode.DerInteger(trustClass);
            net.named_data.jndn.encoding.der.DerNode.DerInteger     extValueTrustLevel = new net.named_data.jndn.encoding.der.DerNode.DerInteger(trustLevel);

            extValueRoot.addChild(extValueName);
            extValueRoot.addChild(extValueTrustClass);
            extValueRoot.addChild(extValueTrustLevel);

            Blob extValueData = extValueRoot.encode();

            String oidString  = "1.3.6.1.5.32.1";
            bool   isCritical = true;
            CertificateExtension certExtension = new CertificateExtension(
                oidString, isCritical, extValueData);

            toyCert.encode();
            Certificate cert = new Certificate(toyCert);

            cert.addExtension(certExtension);

            cert.encode();
            Blob certData  = cert.getContent();
            Data plainData = new Data();

            plainData.setContent(certData);
            // The constructor Certificate(Data) calls decode().
            Certificate decodedCert = new Certificate(plainData);

            Assert.AssertEquals("Wrong number of certificate extensions after decoding",
                                1, decodedCert.getExtensionList().Count);

            CertificateExtension decodedExtension = (CertificateExtension)decodedCert
                                                    .getExtensionList()[0];

            Assert.AssertEquals("Certificate extension has the wrong OID after decoding",
                                oidString, "" + decodedExtension.getOid());
            Assert.AssertEquals(
                "Certificate extension has the wrong isCritical value after decoding",
                isCritical, decodedExtension.getIsCritical());

            // Decode and check the extension value.
            DerNode parsedExtValue = net.named_data.jndn.encoding.der.DerNode.parse(decodedExtension.getValue()
                                                                                    .buf());
            IList decodedExtValueRoot = parsedExtValue.getChildren();

            Assert.AssertEquals(
                "Wrong number of certificate extension value items after decoding",
                3, decodedExtValueRoot.Count);

            net.named_data.jndn.encoding.der.DerNode.DerOctetString decodedName       = (net.named_data.jndn.encoding.der.DerNode.DerOctetString)decodedExtValueRoot[0];
            net.named_data.jndn.encoding.der.DerNode.DerInteger     decodedTrustClass = (net.named_data.jndn.encoding.der.DerNode.DerInteger)decodedExtValueRoot[1];
            net.named_data.jndn.encoding.der.DerNode.DerInteger     decodedTrustLevel = (net.named_data.jndn.encoding.der.DerNode.DerInteger)decodedExtValueRoot[2];
            Assert.AssertEquals("Wrong extension value name after decoding", name, ""
                                + decodedName.toVal());
            Assert.AssertEquals("Wrong extension value trust class after decoding",
                                trustClass, (int)(Int32)decodedTrustClass.toVal());
            Assert.AssertEquals("Wrong extension value trust level after decoding",
                                trustLevel, (int)(Int32)decodedTrustLevel.toVal());
        }
예제 #10
0
        /// <summary>
        /// Create a new PublicKey by decoding the keyDer. Set the key type from the
        /// decoding.
        /// </summary>
        ///
        /// <param name="keyDer">The blob of the SubjectPublicKeyInfo DER.</param>
        /// <exception cref="UnrecognizedKeyFormatException">if can't decode the key DER.</exception>
        public PublicKey(Blob keyDer)
        {
            keyDer_ = keyDer;

            // Get the public key OID.
            String oidString = null;

            try {
                DerNode parsedNode          = net.named_data.jndn.encoding.der.DerNode.parse(keyDer.buf(), 0);
                IList   rootChildren        = parsedNode.getChildren();
                IList   algorithmIdChildren = net.named_data.jndn.encoding.der.DerNode.getSequence(rootChildren, 0)
                                              .getChildren();
                oidString = "" + ((DerNode)algorithmIdChildren[0]).toVal();
            } catch (DerDecodingException ex) {
                throw new UnrecognizedKeyFormatException(
                          "PublicKey: Error decoding the public key: "
                          + ex.Message);
            }

            // Verify that the we can decode.
            if (oidString.equals(RSA_ENCRYPTION_OID))
            {
                keyType_ = net.named_data.jndn.security.KeyType.RSA;

                KeyFactory keyFactory = null;
                try {
                    keyFactory = System.KeyFactory.getInstance("RSA");
                } catch (Exception exception) {
                    // Don't expect this to happen.
                    throw new UnrecognizedKeyFormatException(
                              "RSA is not supported: " + exception.Message);
                }

                try {
                    keyFactory.generatePublic(new X509EncodedKeySpec(keyDer
                                                                     .getImmutableArray()));
                } catch (InvalidKeySpecException exception_0) {
                    // Don't expect this to happen.
                    throw new UnrecognizedKeyFormatException(
                              "X509EncodedKeySpec is not supported for RSA: "
                              + exception_0.Message);
                }
            }
            else if (oidString.equals(EC_ENCRYPTION_OID))
            {
                keyType_ = net.named_data.jndn.security.KeyType.ECDSA;

                KeyFactory keyFactory_1 = null;
                try {
                    keyFactory_1 = System.KeyFactory.getInstance("EC");
                } catch (Exception exception_2) {
                    // Don't expect this to happen.
                    throw new UnrecognizedKeyFormatException(
                              "EC is not supported: " + exception_2.Message);
                }

                try {
                    keyFactory_1.generatePublic(new X509EncodedKeySpec(keyDer
                                                                       .getImmutableArray()));
                } catch (InvalidKeySpecException exception_3) {
                    // Don't expect this to happen.
                    throw new UnrecognizedKeyFormatException(
                              "X509EncodedKeySpec is not supported for EC: "
                              + exception_3.Message);
                }
            }
            else
            {
                throw new UnrecognizedKeyFormatException(
                          "PublicKey: Unrecognized OID " + oidString);
            }
        }
예제 #11
0
        /// <summary>
        /// Get the private key for this name; internal helper method
        /// </summary>
        ///
        /// <param name="keyName">The name of the key.</param>
        /// <param name="keyType">Set keyType[0] to the KeyType.</param>
        /// <returns>The java.security.PrivateKey.</returns>
        /// <exception cref="System.Security.SecurityException"></exception>
        private PrivateKey getPrivateKey(Name keyName, KeyType[] keyType)
        {
            if (!doesKeyExist(keyName, net.named_data.jndn.security.KeyClass.PRIVATE))
            {
                throw new SecurityException(
                          "FilePrivateKeyStorage: Private key does not exist.");
            }

            // Read the file contents.
            byte[] der = this.read(keyName, net.named_data.jndn.security.KeyClass.PRIVATE);

            // Decode the PKCS #8 DER to find the algorithm OID.
            String oidString = null;

            try {
                DerNode parsedNode          = net.named_data.jndn.encoding.der.DerNode.parse(ILOG.J2CsMapping.NIO.ByteBuffer.wrap(der), 0);
                IList   pkcs8Children       = parsedNode.getChildren();
                IList   algorithmIdChildren = net.named_data.jndn.encoding.der.DerNode.getSequence(pkcs8Children, 1)
                                              .getChildren();
                oidString = ""
                            + ((DerNode.DerOid)algorithmIdChildren[0]).toVal();
            } catch (DerDecodingException ex) {
                throw new SecurityException(
                          "Cannot decode the PKCS #8 private key: " + ex);
            }

            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(der);

            if (oidString.equals(RSA_ENCRYPTION_OID))
            {
                keyType[0] = net.named_data.jndn.security.KeyType.RSA;

                try {
                    KeyFactory kf = System.KeyFactory.getInstance("RSA");
                    return(kf.generatePrivate(spec));
                } catch (InvalidKeySpecException e) {
                    // Don't expect this to happen.
                    throw new SecurityException(
                              "FilePrivateKeyStorage: RSA is not supported: "
                              + e.Message);
                } catch (Exception e_0) {
                    // Don't expect this to happen.
                    throw new SecurityException(
                              "FilePrivateKeyStorage: PKCS8EncodedKeySpec is not supported for RSA: "
                              + e_0.Message);
                }
            }
            else if (oidString.equals(EC_ENCRYPTION_OID))
            {
                keyType[0] = net.named_data.jndn.security.KeyType.EC;

                try {
                    KeyFactory kf_1 = System.KeyFactory.getInstance("EC");
                    return(kf_1.generatePrivate(spec));
                } catch (InvalidKeySpecException e_2) {
                    // Don't expect this to happen.
                    throw new SecurityException(
                              "FilePrivateKeyStorage: EC is not supported: "
                              + e_2.Message);
                } catch (Exception e_3) {
                    // Don't expect this to happen.
                    throw new SecurityException(
                              "FilePrivateKeyStorage: PKCS8EncodedKeySpec is not supported for EC: "
                              + e_3.Message);
                }
            }
            else
            {
                throw new SecurityException(
                          "FilePrivateKeyStorage.sign: Unrecognized private key OID: "
                          + oidString);
            }
        }
예제 #12
0
        /// <summary>
        /// Load the encrypted private key from a buffer with the PKCS #8 encoding of
        /// the EncryptedPrivateKeyInfo.
        /// This replaces any existing private key in this object. This partially
        /// decodes the private key to determine the key type.
        /// </summary>
        ///
        /// <param name="encoding">The byte buffer with the private key encoding.</param>
        /// <param name="password"></param>
        /// <exception cref="TpmPrivateKey.Error">for errors decoding or decrypting the key.</exception>
        public void loadEncryptedPkcs8(ByteBuffer encoding,
                                       ByteBuffer password)
        {
            // Decode the PKCS #8 EncryptedPrivateKeyInfo.
            // See https://tools.ietf.org/html/rfc5208.
            String oidString;
            Object parameters;
            Blob   encryptedKey;

            try {
                DerNode parsedNode             = net.named_data.jndn.encoding.der.DerNode.parse(encoding, 0);
                IList   encryptedPkcs8Children = parsedNode.getChildren();
                IList   algorithmIdChildren    = net.named_data.jndn.encoding.der.DerNode.getSequence(
                    encryptedPkcs8Children, 0).getChildren();
                oidString = ""
                            + ((DerNode.DerOid)algorithmIdChildren[0]).toVal();
                parameters = algorithmIdChildren[1];

                encryptedKey = (Blob)((DerNode.DerOctetString)encryptedPkcs8Children[1]).toVal();
            } catch (Exception ex) {
                throw new TpmPrivateKey.Error(
                          "Cannot decode the PKCS #8 EncryptedPrivateKeyInfo: " + ex);
            }

            // Use the password to get the unencrypted pkcs8Encoding.
            byte[] pkcs8Encoding;
            if (oidString.equals(PBES2_OID))
            {
                // Decode the PBES2 parameters. See https://www.ietf.org/rfc/rfc2898.txt .
                String keyDerivationOidString;
                Object keyDerivationParameters;
                String encryptionSchemeOidString;
                Object encryptionSchemeParameters;
                try {
                    IList parametersChildren = ((DerNode.DerSequence)parameters)
                                               .getChildren();

                    IList keyDerivationAlgorithmIdChildren = net.named_data.jndn.encoding.der.DerNode.getSequence(
                        parametersChildren, 0).getChildren();
                    keyDerivationOidString = ""
                                             + ((DerNode.DerOid)keyDerivationAlgorithmIdChildren[0]).toVal();
                    keyDerivationParameters = keyDerivationAlgorithmIdChildren[1];

                    IList encryptionSchemeAlgorithmIdChildren = net.named_data.jndn.encoding.der.DerNode.getSequence(
                        parametersChildren, 1).getChildren();
                    encryptionSchemeOidString = ""
                                                + ((DerNode.DerOid)encryptionSchemeAlgorithmIdChildren[0]).toVal();
                    encryptionSchemeParameters = encryptionSchemeAlgorithmIdChildren[1];
                } catch (Exception ex_0) {
                    throw new TpmPrivateKey.Error(
                              "Cannot decode the PBES2 parameters: " + ex_0);
                }

                // Get the derived key from the password.
                byte[] derivedKey = null;
                if (keyDerivationOidString.equals(PBKDF2_OID))
                {
                    // Decode the PBKDF2 parameters.
                    Blob salt;
                    int  nIterations;
                    try {
                        IList pbkdf2ParametersChildren = ((DerNode.DerSequence)keyDerivationParameters)
                                                         .getChildren();
                        salt        = (Blob)((DerNode.DerOctetString)pbkdf2ParametersChildren[0]).toVal();
                        nIterations = (int)((DerNode.DerInteger)pbkdf2ParametersChildren[1]).toVal();
                    } catch (Exception ex_1) {
                        throw new TpmPrivateKey.Error(
                                  "Cannot decode the PBES2 parameters: " + ex_1);
                    }

                    // Check the encryption scheme here to get the needed result length.
                    int resultLength;
                    if (encryptionSchemeOidString.equals(DES_EDE3_CBC_OID))
                    {
                        resultLength = DES_EDE3_KEY_LENGTH;
                    }
                    else
                    {
                        throw new TpmPrivateKey.Error(
                                  "Unrecognized PBES2 encryption scheme OID: "
                                  + encryptionSchemeOidString);
                    }

                    try {
                        derivedKey = net.named_data.jndn.util.Common.computePbkdf2WithHmacSha1(new Blob(
                                                                                                   password, false).getImmutableArray(), salt
                                                                                               .getImmutableArray(), nIterations, resultLength);
                    } catch (Exception ex_2) {
                        throw new TpmPrivateKey.Error(
                                  "Error computing the derived key using PBKDF2 with HMAC SHA1: "
                                  + ex_2);
                    }
                }
                else
                {
                    throw new TpmPrivateKey.Error(
                              "Unrecognized PBES2 key derivation OID: "
                              + keyDerivationOidString);
                }

                // Use the derived key to get the unencrypted pkcs8Encoding.
                if (encryptionSchemeOidString.equals(DES_EDE3_CBC_OID))
                {
                    // Decode the DES-EDE3-CBC parameters.
                    Blob initialVector;
                    try {
                        initialVector = (Blob)((DerNode.DerOctetString)encryptionSchemeParameters)
                                        .toVal();
                    } catch (Exception ex_3) {
                        throw new TpmPrivateKey.Error(
                                  "Cannot decode the DES-EDE3-CBC parameters: " + ex_3);
                    }

                    try {
                        Cipher cipher = javax.crypto.Cipher
                                        .getInstance("DESede/CBC/PKCS5Padding");
                        cipher.init(javax.crypto.Cipher.DECRYPT_MODE, new SecretKeySpec(
                                        derivedKey, "DESede"), new IvParameterSpec(
                                        initialVector.getImmutableArray()));
                        pkcs8Encoding = cipher.doFinal(encryptedKey
                                                       .getImmutableArray());
                    } catch (Exception ex_4) {
                        throw new TpmPrivateKey.Error(
                                  "Error decrypting PKCS #8 key with DES-EDE3-CBC: "
                                  + ex_4);
                    }
                }
                else
                {
                    throw new TpmPrivateKey.Error(
                              "Unrecognized PBES2 encryption scheme OID: "
                              + encryptionSchemeOidString);
                }
            }
            else
            {
                throw new TpmPrivateKey.Error(
                          "Unrecognized PKCS #8 EncryptedPrivateKeyInfo OID: "
                          + oidString);
            }

            loadPkcs8(ILOG.J2CsMapping.NIO.ByteBuffer.wrap(pkcs8Encoding));
        }
예제 #13
0
        /// <summary>
        /// Load the unencrypted private key from a buffer with the PKCS #8 encoding.
        /// This replaces any existing private key in this object.
        /// </summary>
        ///
        /// <param name="encoding">The byte buffer with the private key encoding.</param>
        /// <param name="keyType"></param>
        /// <exception cref="TpmPrivateKey.Error">for errors decoding the key.</exception>
        public void loadPkcs8(ByteBuffer encoding, KeyType keyType)
        {
            if (keyType == null)
            {
                // Decode the PKCS #8 DER to find the algorithm OID.
                String oidString = null;
                try {
                    DerNode parsedNode          = net.named_data.jndn.encoding.der.DerNode.parse(encoding, 0);
                    IList   pkcs8Children       = parsedNode.getChildren();
                    IList   algorithmIdChildren = net.named_data.jndn.encoding.der.DerNode
                                                  .getSequence(pkcs8Children, 1).getChildren();
                    oidString = ""
                                + ((DerNode.DerOid)algorithmIdChildren[0]).toVal();
                } catch (DerDecodingException ex) {
                    throw new TpmPrivateKey.Error(
                              "Cannot decode the PKCS #8 private key: " + ex);
                }

                if (oidString.equals(EC_ENCRYPTION_OID))
                {
                    keyType = net.named_data.jndn.security.KeyType.EC;
                }
                else if (oidString.equals(RSA_ENCRYPTION_OID))
                {
                    keyType = net.named_data.jndn.security.KeyType.RSA;
                }
                else
                {
                    throw new TpmPrivateKey.Error(
                              "loadPkcs8: Unrecognized private key OID: " + oidString);
                }
            }

            // Use a Blob to get the byte array.
            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(new Blob(encoding,
                                                                        false).getImmutableArray());

            if (keyType == net.named_data.jndn.security.KeyType.EC)
            {
                try {
                    KeyFactory kf = System.KeyFactory.getInstance("EC");
                    privateKey_ = kf.generatePrivate(spec);
                    keyType_    = net.named_data.jndn.security.KeyType.EC;
                } catch (InvalidKeySpecException ex_0) {
                    // Don't expect this to happen.
                    throw new TpmPrivateKey.Error(
                              "loadPkcs8: EC is not supported: " + ex_0);
                } catch (Exception ex_1) {
                    // Don't expect this to happen.
                    throw new TpmPrivateKey.Error(
                              "loadPkcs8: PKCS8EncodedKeySpec is not supported for EC: "
                              + ex_1);
                }
            }
            else if (keyType == net.named_data.jndn.security.KeyType.RSA)
            {
                try {
                    KeyFactory kf_2 = System.KeyFactory.getInstance("RSA");
                    privateKey_ = kf_2.generatePrivate(spec);
                    keyType_    = net.named_data.jndn.security.KeyType.RSA;
                } catch (InvalidKeySpecException ex_3) {
                    // Don't expect this to happen.
                    throw new TpmPrivateKey.Error(
                              "loadPkcs8: RSA is not supported: " + ex_3);
                } catch (Exception ex_4) {
                    // Don't expect this to happen.
                    throw new TpmPrivateKey.Error(
                              "loadPkcs8: PKCS8EncodedKeySpec is not supported for RSA: "
                              + ex_4);
                }
            }
            else
            {
                throw new TpmPrivateKey.Error("loadPkcs8: Unrecognized keyType: "
                                              + keyType);
            }
        }