starting working on activity

This commit is contained in:
Nicolas Constant
2020-06-06 01:29:13 -04:00
parent e1ef37d504
commit 4875e71340
17 changed files with 329 additions and 5 deletions

View File

@ -1,24 +1,33 @@
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using BirdsiteLive.ActivityPub;
using BirdsiteLive.Common.Settings;
using BirdsiteLive.Cryptography;
using BirdsiteLive.Twitter.Models;
using Tweetinvi.Core.Exceptions;
namespace BirdsiteLive.Domain
{
public interface IUserService
{
Actor GetUser(TwitterUser twitterUser);
Task<bool> FollowRequestedAsync(string signature, string method, string path, string queryString, Dictionary<string, string> requestHeaders, ActivityFollow activity);
}
public class UserService : IUserService
{
private readonly ICryptoService _cryptoService;
private readonly IActivityPubService _activityPubService;
private readonly string _host;
#region Ctor
public UserService(InstanceSettings instanceSettings, ICryptoService cryptoService)
public UserService(InstanceSettings instanceSettings, ICryptoService cryptoService, IActivityPubService activityPubService)
{
_cryptoService = cryptoService;
_activityPubService = activityPubService;
_host = $"https://{instanceSettings.Domain.Replace("https://",string.Empty).Replace("http://", string.Empty).TrimEnd('/')}";
}
#endregion
@ -53,5 +62,78 @@ namespace BirdsiteLive.Domain
};
return user;
}
public async Task<bool> FollowRequestedAsync(string signature, string method, string path, string queryString, Dictionary<string, string> requestHeaders, ActivityFollow activity)
{
// Validate
if (!await ValidateSignature(activity.actor, signature, method, path, queryString, requestHeaders)) return false;
// Save Follow in DB
// Send Accept Activity
throw new NotImplementedException();
}
private async Task<bool> ValidateSignature(string actor, string rawSig, string method, string path, string queryString, Dictionary<string, string> requestHeaders)
{
var signatures = rawSig.Split(',');
var signature_header = new Dictionary<string, string>();
foreach (var signature in signatures)
{
var splitSig = signature.Replace("\"", string.Empty).Split('=');
signature_header.Add(splitSig[0], splitSig[1]);
}
signature_header["signature"] = signature_header["signature"] + "==";
var key_id = signature_header["keyId"];
var headers = signature_header["headers"];
var algorithm = signature_header["algorithm"];
var sig = Convert.FromBase64String(signature_header["signature"]);
var remoteUser = await _activityPubService.GetUser(actor);
var toDecode = remoteUser.publicKey.publicKeyPem.Trim().Remove(0, remoteUser.publicKey.publicKeyPem.IndexOf('\n'));
toDecode = toDecode.Remove(toDecode.LastIndexOf('\n')).Replace("\n", "");
var signKey = ASN1.ToRSA(Convert.FromBase64String(toDecode));
var toSign = new StringBuilder();
//var comparisonString = headers.Split(' ').Select(signed_header_name =>
//{
// if (signed_header_name == "(request-target)")
// return "(request-target): post /inbox";
// else
// return $"{signed_header_name}: {r.Headers[signed_header_name.ToUpperInvariant()]}";
//});
foreach (var headerKey in headers.Split(' '))
{
if (headerKey == "(request-target)") toSign.Append($"(request-target): {method.ToLower()} {path}{queryString}\n");
else toSign.Append($"{headerKey}: {string.Join(", ", requestHeaders[headerKey])}\n");
}
toSign.Remove(toSign.Length - 1, 1);
//var signKey = ASN1.ToRSA(Convert.FromBase64String(toDecode));
//new RSACryptoServiceProvider(keyId.publicKey.publicKeyPem);
//Create a new instance of RSACryptoServiceProvider.
RSACryptoServiceProvider key = new RSACryptoServiceProvider();
//Get an instance of RSAParameters from ExportParameters function.
RSAParameters RSAKeyInfo = key.ExportParameters(false);
//Set RSAKeyInfo to the public key values.
RSAKeyInfo.Modulus = Convert.FromBase64String(toDecode);
key.ImportParameters(RSAKeyInfo);
var result = signKey.VerifyData(Encoding.UTF8.GetBytes(toSign.ToString()), sig, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
return result;
}
}
}