/// <summary>
        ///   Create a key ID for the key.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks>
        ///   The key id is the SHA-256 multihash of its public key. The public key is
        ///   a protobuf encoding containing a type and
        ///   the DER encoding of the PKCS SubjectPublicKeyInfo.
        /// </remarks>
        MultiHash CreateKeyId(AsymmetricKeyParameter key)
        {
            var spki = SubjectPublicKeyInfoFactory
                       .CreateSubjectPublicKeyInfo(key)
                       .GetDerEncoded();

            // Add protobuf cruft.
            var publicKey = new Proto.PublicKey
            {
                Data = spki
            };

            if (key is RsaKeyParameters)
            {
                publicKey.Type = Proto.KeyType.RSA;
            }
            else if (key is ECPublicKeyParameters)
            {
                publicKey.Type = Proto.KeyType.Secp256k1;
            }
            else
            {
                throw new NotSupportedException($"The key type {key.GetType().Name} is not supported.");
            }

            using (var ms = new MemoryStream())
            {
                ProtoBuf.Serializer.Serialize(ms, publicKey);
                ms.Position = 0;
                return(MultiHash.ComputeHash(ms, "sha2-256"));
            }
        }
        /// <summary>
        ///   Gets the IPFS encoded public key for the specified key.
        /// </summary>
        /// <param name="name">
        ///   The local name of the key.
        /// </param>
        /// <param name="cancel">
        ///   Is used to stop the task.  When cancelled, the <see cref="TaskCanceledException"/> is raised.
        /// </param>
        /// <returns>
        ///   A task that represents the asynchronous operation. The task's result is
        ///   the IPFS encoded public key.
        /// </returns>
        /// <remarks>
        ///   The IPFS public key is the base-64 encoding of a protobuf encoding containing
        ///   a type and the DER encoding of the PKCS Subject Public Key Info.
        /// </remarks>
        /// <seealso href="https://tools.ietf.org/html/rfc5280#section-4.1.2.7"/>
        public async Task <string> GetPublicKeyAsync(string name, CancellationToken cancel = default(CancellationToken))
        {
            string result = null;

            using (var repo = await ipfs.Repository(cancel))
            {
                var ekey = await repo.EncryptedKeys
                           .Where(k => k.Name == name)
                           .FirstOrDefaultAsync(cancel);

                if (ekey != null)
                {
                    UseEncryptedKey(ekey, key =>
                    {
                        var kp   = GetKeyPairFromPrivateKey(key);
                        var spki = SubjectPublicKeyInfoFactory
                                   .CreateSubjectPublicKeyInfo(kp.Public)
                                   .GetDerEncoded();
                        // Add protobuf cruft.
                        var publicKey = new Proto.PublicKey
                        {
                            Data = spki
                        };
                        if (kp.Public is RsaKeyParameters)
                        {
                            publicKey.Type = Proto.KeyType.RSA;
                        }
                        else if (kp.Public is ECPublicKeyParameters)
                        {
                            publicKey.Type = Proto.KeyType.Secp256k1;
                        }
                        else
                        {
                            throw new NotSupportedException($"The key type {kp.Public.GetType().Name} is not supported.");
                        }

                        using (var ms = new MemoryStream())
                        {
                            ProtoBuf.Serializer.Serialize(ms, publicKey);
                            result = Convert.ToBase64String(ms.ToArray());
                        }
                    });
                }
            }
            return(result);
        }
示例#3
0
        /// <summary>
        ///   Gets the IPFS encoded public key for the specified key.
        /// </summary>
        /// <param name="name">
        ///   The local name of the key.
        /// </param>
        /// <param name="cancel">
        ///   Is used to stop the task.  When cancelled, the <see cref="TaskCanceledException"/> is raised.
        /// </param>
        /// <returns>
        ///   A task that represents the asynchronous operation. The task's result is
        ///   the IPFS encoded public key.
        /// </returns>
        /// <remarks>
        ///   The IPFS public key is the base-64 encoding of a protobuf encoding containing
        ///   a type and the DER encoding of the PKCS Subject Public Key Info.
        /// </remarks>
        /// <seealso href="https://tools.ietf.org/html/rfc5280#section-4.1.2.7"/>
        public async Task <string> GetPublicKeyAsync(string name, CancellationToken cancel = default(CancellationToken))
        {
            // TODO: Rename to GetIpfsPublicKeyAsync
            string result = null;
            var    ekey   = await Store.TryGetAsync(name, cancel).ConfigureAwait(false);

            if (ekey != null)
            {
                UseEncryptedKey(ekey, key =>
                {
                    var kp   = GetKeyPairFromPrivateKey(key);
                    var spki = SubjectPublicKeyInfoFactory
                               .CreateSubjectPublicKeyInfo(kp.Public)
                               .GetDerEncoded();
                    // Add protobuf cruft.
                    var publicKey = new Proto.PublicKey
                    {
                        Data = spki
                    };
                    if (kp.Public is RsaKeyParameters)
                    {
                        publicKey.Type = Proto.KeyType.RSA;
                    }
                    else if (kp.Public is Ed25519PublicKeyParameters)
                    {
                        publicKey.Type = Proto.KeyType.Ed25519;
                    }
                    else if (kp.Public is ECPublicKeyParameters)
                    {
                        publicKey.Type = Proto.KeyType.Secp256k1;
                    }
                    else
                    {
                        throw new NotSupportedException($"The key type {kp.Public.GetType().Name} is not supported.");
                    }

                    using (var ms = new MemoryStream())
                    {
                        ProtoBuf.Serializer.Serialize(ms, publicKey);
                        result = Convert.ToBase64String(ms.ToArray());
                    }
                });
            }
            return(result);
        }
示例#4
0
        /// <summary>
        ///   Create a key ID for the key.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <remarks>
        ///   The key id is the SHA-256 multihash of its public key. The public key is
        ///   a protobuf encoding containing a type and
        ///   the DER encoding of the PKCS SubjectPublicKeyInfo.
        /// </remarks>
        MultiHash CreateKeyId(AsymmetricKeyParameter key)
        {
            var spki = SubjectPublicKeyInfoFactory
                       .CreateSubjectPublicKeyInfo(key)
                       .GetDerEncoded();

            // Add protobuf cruft.
            var publicKey = new Proto.PublicKey
            {
                Data = spki
            };

            if (key is RsaKeyParameters)
            {
                publicKey.Type = Proto.KeyType.RSA;
            }
            else if (key is ECPublicKeyParameters)
            {
                publicKey.Type = Proto.KeyType.Secp256k1;
            }
            else if (key is Ed25519PublicKeyParameters)
            {
                publicKey.Type = Proto.KeyType.Ed25519;
            }
            else
            {
                throw new NotSupportedException($"The key type {key.GetType().Name} is not supported.");
            }

            using (var ms = new MemoryStream())
            {
                ProtoBuf.Serializer.Serialize(ms, publicKey);

                // If the length of the serialized bytes <= 42, then we compute the "identity" multihash of
                // the serialized bytes. The idea here is that if the serialized byte array
                // is short enough, we can fit it in a multihash verbatim without having to
                // condense it using a hash function.
                var alg = (ms.Length <= 48) ? "identity" : "sha2-256";

                ms.Position = 0;
                return(MultiHash.ComputeHash(ms, alg));
            }
        }