Beispiel #1
0
        public CoaliteResource Action(CoaliteActionRequest coaliteActionRequest)
        {
            // Validate whole request
            var buffer    = Encoding.UTF8.GetBytes(coaliteActionRequest.GetAsSignablePayload());
            var signature = Convert.FromBase64String(coaliteActionRequest.Signature);
            var clientRsa = RSA.Create();
            int bytesReadPk;
            var pk = coaliteActionRequest.SignerPublicKey.Split(' ').OrderByDescending(s => s.Length).FirstOrDefault();

            clientRsa.ImportRSAPublicKey(Convert.FromBase64String(pk), out bytesReadPk);
            if (!clientRsa.VerifyData(buffer, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1))
            {
                throw new CoalitingException((int)HttpStatusCode.BadRequest,
                                             "Signature does not match public key");
            }

            Coalite coalite;

            lock (_dblock)
            {
                var dbcontext = GetDBConnection();
                coalite =
                    dbcontext.Coalites
                    .Where(c => c.Coalid == coaliteActionRequest.Coalite.Coalid)
                    .FirstOrDefault();
                if (coalite == null)
                {
                    throw new CoalitingException((int)HttpStatusCode.BadRequest,
                                                 "Unexisting coalite");
                }

                if (!coalite.EqualToResource(coaliteActionRequest.Coalite))
                {
                    throw new CoalitingException((int)HttpStatusCode.BadRequest,
                                                 "Referenced coalite does not match last known coalite state");
                }

                var payload = coalite.LoadPayload();

                // Find coalite owner
                var lastClaimAction = payload.Signatures.LastOrDefault(s => s.Action == CoaliteAction.CLAIM);

                // Case 1: No owner and action is to claim
                // Case 2: Check if claimer has ownership rights
                if (lastClaimAction != null && lastClaimAction.SignerPublicKey != coaliteActionRequest.SignerPublicKey)
                {
                    throw new CoalitingException((int)HttpStatusCode.BadRequest,
                                                 "Coalite not owned by claimer public key");
                }

                coalite.AppendSignedAction(coaliteActionRequest.Action,
                                           coaliteActionRequest.ActionPayload,
                                           coaliteActionRequest.SignerPublicKey,
                                           coaliteActionRequest.SignerId,
                                           coaliteActionRequest.ActionSignature);
                coalite.SignCoalite(_rsa, CoaliteAction.ACCEPT, "", _serverPublicKey, "System");

                if (coaliteActionRequest.Action == CoaliteAction.CLAIM)
                {
                    coalite.ClaimedBy = coaliteActionRequest.SignerId;
                }

                dbcontext.Update(coalite);
                dbcontext.SaveChanges();

                return(new CoaliteResource(coalid: coalite.Coalid,
                                           signatures: coalite.LoadPayload().Signatures,
                                           seqid: coalite.FullSecondStamp,
                                           timestamp: _baseDate + TimeSpan.FromSeconds(coalite.FullSecondStamp)));
            }
        }
Beispiel #2
0
        public ActionResult <CoaliteResource> Action([FromBody] CoaliteActionRequest coaliteActionRequest)
        {
            var coalite = _coaliter.Action(coaliteActionRequest);

            return(Ok(coalite));
        }