public async Task <JWKEntry> GetKey(APEntity actor, string kid = null) { if (!actor.IsOwner) { if (kid == null) { return(null); // can't do that for remote actors } var key = await _context.JsonWebKeys.FirstOrDefaultAsync(a => a.Owner == actor && a.Id == kid); if (key == null) { // well here we go var endpoints = actor.Data["endpoints"].FirstOrDefault(); if (endpoints == null) { return(null); } ASObject endpointsData; if (endpoints.Primitive != null) { endpointsData = (await _store.GetEntity((string)endpoints.Primitive, true)).Data; } else { endpointsData = endpoints.SubObject; } var jwks = (string)endpointsData["jwks"].FirstOrDefault()?.Primitive; // not actually an entity! if (jwks == null) { return(null); } var keys = await _getKey(jwks); var jwkey = keys.Keys.FirstOrDefault(a => a.Kid == kid); if (jwkey == null) { return(null); // couldn't find key } key = new JWKEntry { Owner = actor, Id = kid, SerializedData = JsonConvert.SerializeObject(jwkey) }; _context.JsonWebKeys.Add(key); await _context.SaveChangesAsync(); } return(key); } else { var key = await _context.JsonWebKeys.FirstOrDefaultAsync(a => a.Owner == actor); if (key == null) { var jwk = new JsonWebKey(); jwk.KeyOps.Add("sign"); jwk.Kty = "EC"; jwk.Crv = "P-256"; jwk.Use = JsonWebKeyUseNames.Sig; jwk.Kid = Guid.NewGuid().ToString().Substring(0, 8); var ec = ECDsa.Create(ECCurve.NamedCurves.nistP256); var parms = ec.ExportParameters(true); jwk.X = Base64UrlEncoder.Encode(parms.Q.X); jwk.Y = Base64UrlEncoder.Encode(parms.Q.Y); jwk.D = Base64UrlEncoder.Encode(parms.D); key = new JWKEntry { Id = jwk.Kid, Owner = actor, SerializedData = JsonConvert.SerializeObject(jwk) }; _context.JsonWebKeys.Add(key); await _context.SaveChangesAsync(); } return(key); } }
public async Task <JWKEntry> GetJWK(APEntity actor, string kid = null) { if (actor == null) { return(null); } if (!actor.IsOwner) { if (kid == null) { return(null); // can't do that for remote actors } var key = await _connection.QuerySingleOrDefaultAsync <JWKEntry>("select * from \"JsonWebKeys\" where \"OwnerId\" = @OwnerId and \"Id\" = @KeyId", new { OwnerId = actor.DbId, KeyId = kid }); if (key == null) { // well here we go var endpoints = actor.Data["endpoints"].FirstOrDefault(); if (endpoints == null) { return(null); } ASObject endpointsData; if (endpoints.Id != null) { endpointsData = (await _entityStore.GetEntity(endpoints.Id, true)).Data; } else { endpointsData = endpoints.SubObject; } var jwks = endpointsData["jwks"].FirstOrDefault()?.Id; // not actually an entity! if (jwks == null) { return(null); } var keys = await _getKey(jwks); var jwkey = keys.Keys.FirstOrDefault(a => a.Kid == kid); if (jwkey == null) { return(null); // couldn't find key } key = new JWKEntry { OwnerId = actor.DbId, Id = kid, SerializedData = JsonConvert.SerializeObject(jwkey) }; await _connection.ExecuteAsync("insert into \"JsonWebKeys\" (\"OwnerId\", \"Id\", \"SerializedData\") values (@OwnerId, @Id, @SerializedData)", key); } return(key); } else { var key = await _connection.QuerySingleOrDefaultAsync <JWKEntry>("select * from \"JsonWebKeys\" where \"OwnerId\" = @OwnerId", new { OwnerId = actor.DbId }); if (key == null) { var jwk = new JsonWebKey(); jwk.KeyOps.Add("sign"); jwk.Kty = "EC"; jwk.Crv = "P-256"; jwk.Use = JsonWebKeyUseNames.Sig; jwk.Kid = Guid.NewGuid().ToString().Substring(0, 8); var ec = ECDsa.Create(ECCurve.NamedCurves.nistP256); var parms = ec.ExportParameters(true); jwk.X = Base64UrlEncoder.Encode(parms.Q.X); jwk.Y = Base64UrlEncoder.Encode(parms.Q.Y); jwk.D = Base64UrlEncoder.Encode(parms.D); key = new JWKEntry { Id = jwk.Kid, OwnerId = actor.DbId, SerializedData = JsonConvert.SerializeObject(jwk) }; await _connection.ExecuteAsync("insert into \"JsonWebKeys\" (\"OwnerId\", \"Id\", \"SerializedData\") values (@OwnerId, @Id, @SerializedData)", key); } return(key); } }