Example #1
0
        /// <summary>
        /// Loads <see cref="Card"/> from the specified <see cref="RawSignedModel"/>.
        /// </summary>
        /// <param name="cardCrypto">an instance of <see cref="ICardCrypto"/>.</param>
        /// <param name="rawSignedModel">an instance of <see cref="RawSignedModel"/> to get
        /// <see cref="Card"/> from.</param>
        /// <param name="isOutdated"></param>
        /// <returns>Loaded instance of <see cref="Card"/>.</returns>
        public static Card Parse(ICardCrypto cardCrypto, RawSignedModel rawSignedModel, bool isOutdated = false)
        {
            ValidateParams(cardCrypto, rawSignedModel);

            var rawCardContent = SnapshotUtils.ParseSnapshot <RawCardContent>(rawSignedModel.ContentSnapshot);

            var signatures = new List <CardSignature>();

            if (rawSignedModel.Signatures != null)
            {
                foreach (var s in rawSignedModel.Signatures)
                {
                    var cardSignature = new CardSignature
                    {
                        Signer      = s.Signer,
                        Signature   = s.Signature,
                        ExtraFields = TryParseExtraFields(s.Snapshot),
                        Snapshot    = s.Snapshot
                    };
                    signatures.Add(cardSignature);
                }
            }

            return(new Card(
                       GenerateCardId(cardCrypto, rawSignedModel.ContentSnapshot),
                       rawCardContent.Identity,
                       cardCrypto.ImportPublicKey(rawCardContent.PublicKey),
                       rawCardContent.Version,
                       rawCardContent.CreatedAt,
                       signatures,
                       rawCardContent.PreviousCardId,
                       rawSignedModel.ContentSnapshot,
                       isOutdated
                       ));
        }
        private async Task <Card> PublishRawSignedModel(RawSignedModel rawSignedModel,
                                                        TokenContext context,
                                                        IAccessToken accessToken)
        {
            if (this.SignCallBack != null)
            {
                rawSignedModel = await this.SignCallBack.Invoke(rawSignedModel);
            }

            var publishedModel = await TryExecute(
                async (IAccessToken token) =>
            {
                var rawCard = await Client.PublishCardAsync(
                    rawSignedModel,
                    token.ToString()
                    );
                return(rawCard);
            }, context, accessToken);

            if (!rawSignedModel.ContentSnapshot.SequenceEqual(((RawSignedModel)publishedModel).ContentSnapshot))
            {
                throw new CardVerificationException("Publishing returns invalid card");
            }
            var card = CardUtils.Parse(this.CardCrypto, (RawSignedModel)publishedModel);

            this.ValidateCards(new[] { card });

            return(card);
        }
Example #3
0
        private static void ValidateExtendedSignParams(RawSignedModel model, SignParams @params)
        {
            ValidateSignParams(model, @params.SignerPrivateKey);

            if (@params.Signer == null)
            {
                throw new ArgumentException($"{nameof(@params.Signer)} property is mandatory");
            }
        }
        /// <summary>
        /// Publish a new Card using specified <see cref="RawSignedModel"/>.
        /// </summary>
        /// <param name="rawSignedModel">The instance of <see cref="RawSignedModel"/> class.</param>
        /// <returns>The instance of newly published <see cref="Card"/> class.</returns>
        public async Task <Card> PublishCardAsync(RawSignedModel rawSignedModel)
        {
            var cardContent = SnapshotUtils.ParseSnapshot <RawCardContent>(
                rawSignedModel.ContentSnapshot);
            var tokenContext = new TokenContext(cardContent.Identity, "publish");

            var token = await this.AccessTokenProvider.GetTokenAsync(tokenContext);

            return(await PublishRawSignedModel(rawSignedModel, tokenContext, token));
        }
        /// <summary>
        /// Imports and verifies <see cref="Card"/> from an
        /// instance of <see cref="RawSignedModel"/>.
        /// </summary>
        /// <param name="model">an instance of <see cref="RawSignedModel"/>
        /// to get card from.</param>
        /// <returns>Imported and verified card.</returns>
        public Card ImportCard(RawSignedModel model)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }
            var card = CardUtils.Parse(CardCrypto, model);

            this.ValidateCards(new[] { card });
            return(card);
        }
Example #6
0
        private static void ValidateParams(ICardCrypto cardCrypto, RawSignedModel rawSignedModel)
        {
            if (rawSignedModel == null)
            {
                throw new ArgumentNullException(nameof(rawSignedModel));
            }

            if (cardCrypto == null)
            {
                throw new ArgumentNullException(nameof(cardCrypto));
            }
        }
Example #7
0
        private static void ValidateSignParams(RawSignedModel model, IPrivateKey signerPrivateKey)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }


            if (signerPrivateKey == null)
            {
                throw new ArgumentException($"{nameof(signerPrivateKey)} property is mandatory");
            }
        }
Example #8
0
        /// <summary>
        /// Adds owner's signature to the specified <see cref="RawSignedModel"/> using specified signer
        /// parameters included private key and additional raw bytes.
        /// </summary>
        /// <param name="model"> the instance of <see cref="RawSignedModel"/> to be signed.</param>
        /// <param name="signerPrivateKey"> the instance of <see cref="IPrivateKey"/> to sign with.</param>
        /// <param name="signatureSnapshot"> Some additional raw bytes to be signed with model.</param>
        public void SelfSign(RawSignedModel model, IPrivateKey signerPrivateKey, byte[] signatureSnapshot = null)
        {
            ValidateSignParams(model, signerPrivateKey);

            Sign(model,
                 new SignParams()
            {
                SignerPrivateKey = signerPrivateKey,
                Signer           = SelfSigner
            },
                 signatureSnapshot
                 );
        }
Example #9
0
        public static RawSignedModel PredefinedRawSignedModel(this Faker faker,
                                                              string previousCardId   = null,
                                                              bool addSelfSignature   = false,
                                                              bool addVirgilSignature = false,
                                                              bool addExtraSignature  = false
                                                              )
        {
            var crypto         = new VirgilCrypto();
            var keyPair        = faker.PredefinedKeyPair();
            var dateTime       = DateTimeOffset.FromUnixTimeSeconds(Int64.Parse("1515686245")).DateTime;
            var rawCardContent = new RawCardContent()
            {
                CreatedAt      = dateTime,
                Identity       = "test",
                PublicKey      = crypto.ExportPublicKey(keyPair.PublicKey),
                Version        = "5.0",
                PreviousCardId = previousCardId
            };
            var model = new RawSignedModel()
            {
                ContentSnapshot = SnapshotUtils.TakeSnapshot(rawCardContent)
            };

            var signer = new ModelSigner(new VirgilCardCrypto());

            if (addSelfSignature)
            {
                signer.SelfSign(model, keyPair.PrivateKey);
            }

            if (addVirgilSignature)
            {
                signer.Sign(model, new SignParams()
                {
                    Signer           = ModelSigner.VirgilSigner,
                    SignerPrivateKey = faker.PredefinedVirgilKeyPair().PrivateKey
                });
            }

            if (addExtraSignature)
            {
                signer.Sign(model, new SignParams()
                {
                    Signer           = "extra",
                    SignerPrivateKey = crypto.GenerateKeys().PrivateKey
                });
            }
            return(model);
        }
Example #10
0
        /// <summary>
        /// Adds signature to the specified <see cref="RawSignedModel"/> using specified signer
        /// parameters included private key, signer type and additional raw bytes.
        /// </summary>
        /// <param name="model"> the instance of <see cref="RawSignedModel"/> to be signed.</param>
        /// <param name="@params"> the instance of <see cref="SignParams"/> to sign with.</param>
        /// <param name="signatureSnapshot"> Some additional raw bytes to be signed with model.</param>
        public void Sign(RawSignedModel model, SignParams @params, byte[] signatureSnapshot = null)
        {
            ValidateExtendedSignParams(model, @params);
            ThrowExceptionIfSignatureExists(@params, model.Signatures);

            var extendedSnapshot = signatureSnapshot != null?
                                   Bytes.Combine(model.ContentSnapshot, signatureSnapshot)
                                       : model.ContentSnapshot;

            var signatureBytes = Crypto.GenerateSignature(extendedSnapshot, @params.SignerPrivateKey);

            var signature = new RawSignature
            {
                Signer    = @params.Signer,
                Signature = signatureBytes,
                Snapshot  = signatureSnapshot
            };

            model.Signatures.Add(signature);
        }
Example #11
0
        private RawSignedModel GenerateRawSignedModel(string identity)
        {
            var crypto         = new VirgilCrypto();
            var keyPair        = faker.PredefinedKeyPair();
            var rawCardContent = new RawCardContent()
            {
                CreatedAt = DateTime.UtcNow,
                Identity  = identity,
                PublicKey = crypto.ExportPublicKey(keyPair.PublicKey),
                Version   = "5.0"
            };
            var model = new RawSignedModel()
            {
                ContentSnapshot = SnapshotUtils.TakeSnapshot(rawCardContent)
            };

            var signer = new ModelSigner(new VirgilCardCrypto());

            signer.SelfSign(model, keyPair.PrivateKey);
            return(model);
        }
        public async System.Threading.Tasks.Task Prepair_TestDataAsync()
        {
            var model     = faker.PredefinedRawSignedModel();
            var fullModel = faker.PredefinedRawSignedModel(
                "a666318071274adb738af3f67b8c7ec29d954de2cabfd71a942e6ea38e59fff9",
                true, true, true);
            var data = new Dictionary <string, string>
            {
                { "STC-1.as_string", model.ExportAsString() },
                { "STC-1.as_json", model.ExportAsJson() },
                { "STC-2.as_string", fullModel.ExportAsString() },
                { "STC-2.as_json", fullModel.ExportAsJson() }
            };

            var cardManager = faker.CardManager();
            var card        = cardManager.ImportCardFromString(model.ExportAsString());
            var crypto      = new VirgilCrypto();

            data.Add("STC-3.as_string", cardManager.ExportCardAsString(card));
            data.Add("STC-3.as_json", cardManager.ExportCardAsJson(card));
            data.Add("STC-3.card_id", card.Id);
            data.Add("STC-3.public_key_base64", Bytes.ToString(crypto.ExportPublicKey(card.PublicKey), StringEncoding.BASE64));

            fullModel = faker.PredefinedRawSignedModel(null, true, true, true);
            var fullCard = cardManager.ImportCardFromString(fullModel.ExportAsString());

            data.Add("STC-4.as_string", cardManager.ExportCardAsString(fullCard));
            data.Add("STC-4.as_json", cardManager.ExportCardAsJson(fullCard));
            data.Add("STC-4.card_id", fullCard.Id);
            data.Add("STC-4.public_key_base64", Bytes.ToString(crypto.ExportPublicKey(fullCard.PublicKey),
                                                               StringEncoding.BASE64));
            foreach (var signature in fullCard.Signatures)
            {
                data.Add($"STC-4.signature_{signature.Signer}_base64", Bytes.ToString(signature.Signature,
                                                                                      StringEncoding.BASE64));
            }

            string apiPublicKeyId;
            string apiPublicKeyBase64;

            var(token, jwtGenerator) = faker.PredefinedToken(
                new VirgilAccessTokenSigner(),
                TimeSpan.FromMinutes(10),
                out apiPublicKeyId,
                out apiPublicKeyBase64);

            data.Add("STC-22.jwt", token.ToString());
            data.Add("STC-22.api_public_key_base64", apiPublicKeyBase64);
            data.Add("STC-22.api_key_id", apiPublicKeyId);


            data.Add("STC-23.api_public_key_base64", apiPublicKeyBase64);
            data.Add("STC-23.api_key_id", apiPublicKeyId);
            data.Add("STC-23.app_id", jwtGenerator.AppId);

            data.Add("STC-23.api_private_key_base64", Bytes.ToString(
                         crypto.ExportPrivateKey(jwtGenerator.ApiKey), StringEncoding.BASE64));

            // STC-10
            var cardKeyPair     = crypto.GenerateKeys();
            var cardIdentity    = faker.Random.AlphaNumeric(10);
            var rawCardContent1 = new RawCardContent()
            {
                CreatedAt = DateTime.UtcNow,
                Identity  = cardIdentity,
                PublicKey = crypto.ExportPublicKey(cardKeyPair.PublicKey),
                Version   = "5.0",
            };
            var rawSignedModel = new RawSignedModel()
            {
                ContentSnapshot = SnapshotUtils.TakeSnapshot(rawCardContent1)
            };

            var signer = new ModelSigner(new VirgilCardCrypto());

            signer.SelfSign(rawSignedModel, cardKeyPair.PrivateKey);


            var keyPair = crypto.GenerateKeys();

            signer.Sign(rawSignedModel, new SignParams()
            {
                SignerPrivateKey = keyPair.PrivateKey,
                Signer           = "extra"
            });
            data.Add("STC-10.private_key1_base64", Bytes.ToString(
                         crypto.ExportPrivateKey(keyPair.PrivateKey), StringEncoding.BASE64));

            var accessTokenGenerator = new JwtGenerator(
                AppSettings.AppId,
                IntegrationHelper.ApiPrivateKey(),
                AppSettings.ApiPublicKeyId,
                TimeSpan.FromMinutes(10),
                new VirgilAccessTokenSigner()
                );
            var accessTokenProvider = Substitute.For <IAccessTokenProvider>();

            accessTokenProvider.GetTokenAsync(Arg.Any <TokenContext>()).Returns(
                accessTokenGenerator.GenerateToken(cardIdentity)
                );
            var validator = new VirgilCardVerifier(new VirgilCardCrypto())
            {
                VerifySelfSignature = true, VerifyVirgilSignature = true
            };

            validator.ChangeServiceCreds(AppSettings.ServicePublicKeyDerBase64);
            var manager = new CardManager(new CardManagerParams()
            {
                CardCrypto          = new VirgilCardCrypto(),
                AccessTokenProvider = accessTokenProvider,
                ApiUrl   = AppSettings.CardsServiceAddress,
                Verifier = validator
            });

            card = await manager.PublishCardAsync(rawSignedModel);

            data.Add("STC-10.as_string", manager.ExportCardAsString(card));


            // STC - 11
            rawSignedModel = faker.PredefinedRawSignedModel(null, false, false, false);
            data.Add("STC-11.as_string", rawSignedModel.ExportAsString());

            // STC - 12
            rawSignedModel = faker.PredefinedRawSignedModel(null, true, false, false);
            data.Add("STC-12.as_string", rawSignedModel.ExportAsString());

            // STC - 14
            rawSignedModel = faker.PredefinedRawSignedModel(null, false, true, false);
            data.Add("STC-14.as_string", rawSignedModel.ExportAsString());

            // STC - 15
            rawSignedModel = faker.PredefinedRawSignedModel(null, false, false, false);
            keyPair        = crypto.GenerateKeys();
            signer.Sign(rawSignedModel, new SignParams()
            {
                SignerPrivateKey = keyPair.PrivateKey,
                Signer           = "self"
            });
            data.Add("STC-15.as_string", rawSignedModel.ExportAsString());

            // STC - 16
            rawSignedModel = faker.PredefinedRawSignedModel(null, true, true, false);
            keyPair        = crypto.GenerateKeys();
            signer.Sign(rawSignedModel, new SignParams()
            {
                SignerPrivateKey = keyPair.PrivateKey,
                Signer           = "extra"
            });
            data.Add("STC-16.as_string", rawSignedModel.ExportAsString());
            data.Add("STC-16.public_key1_base64", Bytes.ToString(
                         crypto.ExportPublicKey(keyPair.PublicKey), StringEncoding.BASE64));

            // STC - 28
            (token, jwtGenerator) = faker.PredefinedToken(
                new VirgilAccessTokenSigner(),
                TimeSpan.FromMinutes(2),
                out apiPublicKeyId,
                out apiPublicKeyBase64);
            data.Add("STC-28.jwt", token.ToString());
            data.Add("STC-28.jwt_identity", token.BodyContent.Identity);
            data.Add("STC-28.jwt_app_id", token.BodyContent.AppId);
            data.Add("STC-28.jw_issuer", token.BodyContent.Issuer);
            data.Add("STC-28.jwt_subject", token.BodyContent.Subject);
            data.Add("STC-28.jwt_additional_data", Configuration.Serializer.Serialize(token.BodyContent.AdditionalData));
            data.Add("STC-28.jwt_expires_at", Configuration.Serializer.Serialize(token.BodyContent.ExpiresAt));
            data.Add("STC-28.jwt_issued_at", Configuration.Serializer.Serialize(token.BodyContent.IssuedAt));
            data.Add("STC-28.jwt_algorithm", token.HeaderContent.Algorithm);
            data.Add("STC-28.jwt_api_key_id", token.HeaderContent.KeyId);
            data.Add("STC-28.jwt_content_type", token.HeaderContent.ContentType);
            data.Add("STC-28.jwt_type", token.HeaderContent.Type);
            data.Add("STC-28.jwt_signature_base64", Bytes.ToString(token.SignatureData, StringEncoding.BASE64));


            // STC - 29
            (token, jwtGenerator) = faker.PredefinedToken(
                new VirgilAccessTokenSigner(),
                TimeSpan.FromDays(365),
                out apiPublicKeyId,
                out apiPublicKeyBase64);
            data.Add("STC-29.jwt", token.ToString());
            data.Add("STC-29.jwt_identity", token.BodyContent.Identity);
            data.Add("STC-29.jwt_app_id", token.BodyContent.AppId);
            data.Add("STC-29.jw_issuer", token.BodyContent.Issuer);
            data.Add("STC-29.jwt_subject", token.BodyContent.Subject);
            data.Add("STC-29.jwt_additional_data", Configuration.Serializer.Serialize(token.BodyContent.AdditionalData));
            data.Add("STC-29.jwt_expires_at", Configuration.Serializer.Serialize(token.BodyContent.ExpiresAt));
            data.Add("STC-29.jwt_issued_at", Configuration.Serializer.Serialize(token.BodyContent.IssuedAt));
            data.Add("STC-29.jwt_algorithm", token.HeaderContent.Algorithm);
            data.Add("STC-29.jwt_api_key_id", token.HeaderContent.KeyId);
            data.Add("STC-29.jwt_content_type", token.HeaderContent.ContentType);
            data.Add("STC-29.jwt_type", token.HeaderContent.Type);
            data.Add("STC-29.jwt_signature_base64", Bytes.ToString(token.SignatureData, StringEncoding.BASE64));


            // STC - 34
            keyPair = crypto.GenerateKeys();
            var rawCardContent = new RawCardContent()
            {
                CreatedAt = DateTime.UtcNow,
                Identity  = "test",
                PublicKey = crypto.ExportPublicKey(keyPair.PublicKey),
                Version   = "5.0"
            };

            model = new RawSignedModel()
            {
                ContentSnapshot = SnapshotUtils.TakeSnapshot(rawCardContent)
            };

            signer.SelfSign(
                model, keyPair.PrivateKey, new Dictionary <string, string>()
            {
                { "info", "some_additional_info" }
            }
                );

            data.Add("STC-34.private_key_base64", Bytes.ToString(
                         crypto.ExportPrivateKey(keyPair.PrivateKey), StringEncoding.BASE64));
            data.Add("STC-34.public_key_base64", Bytes.ToString(
                         crypto.ExportPublicKey(keyPair.PublicKey), StringEncoding.BASE64));
            data.Add("STC-34.self_signature_snapshot_base64",
                     Bytes.ToString(model.Signatures.First().Snapshot, StringEncoding.BASE64));
            data.Add("STC-34.content_snapshot_base64",
                     Bytes.ToString(
                         SnapshotUtils.TakeSnapshot(rawCardContent), StringEncoding.BASE64));
            data.Add("STC-34.as_string", model.ExportAsString());

            System.IO.File.WriteAllText(AppSettings.OutputTestDataPath,
                                        Configuration.Serializer.Serialize(data));
        }
Example #13
0
 /// /// <summary>
 /// Adds owner's signature to the specified <see cref="RawSignedModel"/> using specified signer
 /// parameters included private key and dictionary with additional data.
 /// </summary>
 /// <param name="model"> the instance of <see cref="RawSignedModel"/> to be signed.</param>
 /// <param name="signerPrivateKey"> the instance of <see cref="IPrivateKey"/> to sign with.</param>
 /// <param name="extraFields"> Dictionary with additional data to be signed with model.</param>
 public void SelfSign(RawSignedModel model, IPrivateKey signerPrivateKey, Dictionary <string, string> extraFields)
 {
     SelfSign(model, signerPrivateKey,
              (extraFields != null) ? SnapshotUtils.TakeSnapshot(extraFields) : null
              );
 }
Example #14
0
 /// <summary>
 /// Adds signature to the specified <see cref="RawSignedModel"/> using specified signer
 /// parameters included private key, signer type and dictionary with additional data.
 /// </summary>
 /// <param name="model"> the instance of <see cref="RawSignedModel"/> to be signed.</param>
 /// <param name="@params"> the instance of <see cref="SignParams"/> to sign with.</param>
 /// <param name="extraFields"> Dictionary with additional data to be signed with model.</param>
 public void Sign(RawSignedModel model, SignParams @params, Dictionary <string, string> ExtraFields)
 {
     Sign(model, @params,
          (ExtraFields != null) ? SnapshotUtils.TakeSnapshot(ExtraFields) : null
          );
 }
Example #15
0
        public void CardManager_Should_RaiseExceptionIfGetsCardWithDifferentId()
        {
            // STC-34
            var verifier = Substitute.For <ICardVerifier>();

            verifier.VerifyCard(Arg.Any <Card>()).Returns(true);
            var crypto         = new VirgilCrypto();
            var keyPair        = faker.PredefinedKeyPair();
            var rawCardContent = new RawCardContent()
            {
                CreatedAt = DateTime.UtcNow,
                Identity  = "test",
                PublicKey = crypto.ExportPublicKey(keyPair.PublicKey),
                Version   = "5.0"
            };
            var model = new RawSignedModel()
            {
                ContentSnapshot = SnapshotUtils.TakeSnapshot(rawCardContent)
            };

            var signer = new ModelSigner(new VirgilCardCrypto());

            signer.SelfSign(
                model, keyPair.PrivateKey, new Dictionary <string, string>()
            {
                { "info", "some_additional_info" }
            }
                );
            var signCallBack = Substitute.For <Func <RawSignedModel, Task <RawSignedModel> > >();

            signCallBack.Invoke(Arg.Any <RawSignedModel>()).Returns(args => (RawSignedModel)args[0]);
            var jwtGenerator = new JwtGenerator(
                AppSettings.AppId,
                IntegrationHelper.ApiPrivateKey(),
                AppSettings.ApiPublicKeyId,
                TimeSpan.FromMinutes(10),
                new VirgilAccessTokenSigner()
                );
            var accessTokenProvider = Substitute.For <IAccessTokenProvider>();
            var identity            = faker.Random.AlphaNumeric(20);
            var token = jwtGenerator.GenerateToken(identity);

            accessTokenProvider.GetTokenAsync(Arg.Any <TokenContext>()).Returns(
                token
                );
            var cardId = faker.CardId();
            var client = Substitute.For <ICardClient>();
            Func <Task <Tuple <RawSignedModel, bool> > > stub = async() =>
            {
                return(new Tuple <RawSignedModel, bool>(model, false));
            };

            client.GetCardAsync(Arg.Any <string>(), Arg.Any <string>()).Returns(stub.Invoke());

            var manager = new CardManager(new CardManagerParams()
            {
                CardCrypto          = new VirgilCardCrypto(),
                AccessTokenProvider = accessTokenProvider,
                SignCallBack        = signCallBack,
                Verifier            = verifier,
                ApiUrl = AppSettings.CardsServiceAddress
            }
                                          )
            {
                Client = client
            };

            Assert.ThrowsAsync <CardVerificationException>(async() => await manager.GetCardAsync(cardId));
        }