/// <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); }
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); }
private static void ValidateParams(ICardCrypto cardCrypto, RawSignedModel rawSignedModel) { if (rawSignedModel == null) { throw new ArgumentNullException(nameof(rawSignedModel)); } if (cardCrypto == null) { throw new ArgumentNullException(nameof(cardCrypto)); } }
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"); } }
/// <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 ); }
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); }
/// <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); }
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)); }
/// /// <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 ); }
/// <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 ); }
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)); }