# Secondary private key that produces limited certificates

I want some notion of a secondary key that behaves like this:

Given a public/private key pair, it is not the private key but rather it is once-removed from it. Like the original private key, it is also not public. Unlike it, it was made for a specific purpose (a string) and has expiration.

The secondary key can produce certificates that prove that the certificate-maker has that secondary key, that the secondary key was produced using the original private key belonging to some public key, for some purpose (a string) with expiration limit, and the token produced is within the expiration limit.

When a user which owns a private key produces a secondary key, they essentially say "I grant the carrier of this token permission to act as me for this purpose for this period of time".

What am I looking for?

Some clarification:

The bearer of the secondary key is some half-trusted code in the user's PC. It cannot carry any secrets other than the secondary key, and it uses it with other users, which are also not trustworthy, so this code cannot pass the secondary key to them, so it needs to be able to generate new certificates from it.

So in diagram it is $A \rightarrow c \rightarrow B$, meaning Alice installs some software $c$ she wants to handle her banking stuff, so she grants a secondary key to $c$ that says they can impersonate her when it comes to banking stuff for a certain amount of time. The code $c$ then interacts with some other user, Bob, producing certificates that means it represents Alice when it comes to banking.

In addition there is no external authority, so everything must be validated locally.

• Can you try again to explain what you want? Or better what is your intended use-case that lead you to wanting this? – cypherfox Mar 23 '18 at 12:22
• I want to give someone ability to generate application-specific-certificates as if they were me for some period of time. – Uri Mar 23 '18 at 13:19
• Sounds like you want to delegate your rights to a third party, optionally with additional provisions. Sound right? If so, take a look at Macaroons. If this is good, then I'll write an answer. Otherwise, I'll need you to expand on what you mean? – cypherfox Mar 23 '18 at 13:25
• It almost sounds like you want a PKI. You have a root key pair that signs a certificate that says something to the effect of "this new key is allowed to do X, Y, and Z and that ability expires on such and such date". – mikeazo Mar 23 '18 at 13:51
• @cypherfox On the contrary, rolling one's own would be overkill here, when a basic use of existing X.509 tools would give exactly what is needed here. – Gilles Mar 24 '18 at 8:56

When a user which owns a private key produces a secondary key, they essentially say "I grant the carrier of this token permission to act as me for this purpose for this period of time".

You could use the original private key to sign that message exactly.

The original keyowner Alice signs a message encoding "The carrier of this signed message has permission to act as me (id/pubkey:XXX) with caveats A,B,C (ie. permissions to _, expires at _)", and gives that signed message to Bob. Bob can now make requests to the server and include that signed permission slip in his requests as his authorization to act as Alice.

You could then change the design to be freely re-delegatable by making the message instead be "The user identified as id/pubkey:YYY has permission to act as me (id/pubkey:XXX) and delegate with caveats ...". Alice can create a message like this specifying Bob's public key as YYY, and give the message to Bob. Bob could make requests to the server including this signed message as his authorization, but could also create his own version of this to delegate permission to Alice's account to Charlie. Bob would give Charlie this new message and Alice's original signed message. Charlie could then make requests to the server and present a chain of messages showing the delegation of permission to Alice's account from Alice to Bob to Charlie.

This final design is pretty much equivalent to Macaroons (see also the answer of cypherfox) with the bonus that anyone could verify the permission slips, not just the server. But if you don't need that, macaroons are likely to be much more compact than using asymmetric crypto.

• And the concrete implementation of this, in practice, is X.509, for which many interoperable libraries exist. – Gilles Mar 24 '18 at 8:55
• I don't think that will work as in my scenario the "server" is just another user, so Bob can't send his permission slip to this other user, as they would be able to just use it themselves. In other words the server is not trustworthy. In addition Bob is just some code running on Alice's computer, so doesn't have its own public key and so cannot prove he is really Bob. I've added this clarification to the question. – Uri Mar 24 '18 at 10:11

Macaroons are a hash-based capability/authority. Please see the full paper and use the following only as a high level demonstration of the concept.

A capability is an unforgeable, unguessable and communicable token of authority. Macaroons are a weaker variant based on a hash function. This is weaker because cryptography is bound probabilistically while pure-capabilities cannot be broken with unlimited computing time.

Macaroons assume a single server mints and verifies the credentials. If you need third parties to verify the authority (without invoking it), then you'll need something asymmetric.

The server possesses a secret key $k$ and an incrementing counter $n$. Each time the server mints a fresh credential, it increments $n$ and sends the user the credential $(n, \text{tag}_0 = \operatorname{HMAC}(k, n))$.

If the server, or any holder of a credential wishes to append additional caveat, aka provision, they compute the triple $(n, \text{caveat}, \text{tag}_1 = \operatorname{HMAC}(\text{tag}_0, \text{caveat}))$.

A common caveat is to restrict the functions you may call, or the objects you may reference. I.e. $f \in {a, b, c}$ allows you to call $a()$ but not $e()$.

If a user wishes to delegate their authority to another user, they sent their credential, with any additional provisions they choose, without contacting the server first. The delegation must occur over a secure channel because secrets are transmitted. The client is responsible for storing their authorities.

The user invokes their authority by producing a final tag, bound to a message instead of a caveat. There is also a flag to distinguish a caveat and the final message.

The invocation reveals the $(n, \text{caveat}, \text{message}, \text{tag}_n)$, all of which are public information. Although you could encrypt these intermediate caveats/messages for partial privacy. Partial because anyone who holds the authority with fewer caveats can recover the message/verify the authority. Alternatively you may use Diffie-Hellman to lock these intermediates out.

• $n$ may be a proxy to a "user identity", one per registration. Never reused. The server may revoke based on the $n$, or caveats may include dynamic conditions like time or to call out to another server. – cypherfox Mar 23 '18 at 14:02
• I'm not sure I fully understood but if it requires some server to authenticate $(n, caveat, message, tag_n)$ it will not work. See my clarification. – Uri Mar 24 '18 at 10:48
• @Uri Okay, in this case Macaroons as-is isn't enough then. However, if you use pairing-friendly elliptic curves, then you can implement this in a similar fashion IIUC. Except using an IBE blinding instead of HMAC. All other properties remain unchanged. Alternatively you may use the fat X.509-style PKI with a fixed authority point and you only get time-based expiration, CRL and OCSP based revocation and any custom caveats must be applied as non-standard extensions/comments in the certificate. The X.509 alternative will have a signature for each step, unlike a tiny Macaroon-style credential. – cypherfox Mar 24 '18 at 11:04
• I do not see why $c$ must verify the integrity of $A$'s authority on $B$? $c$ can "check" the validity locally, then invoke it, and by the time $B$ processes it, it may be invalid. Similarly, $c$ with macaroons wouldn't check by reading the caveats, it'll check by attempting to invoke it. – cypherfox Mar 24 '18 at 11:09
• "No external authority" would include the bank $B$, so this rules PKI/X.509 out already, which contradicts with "verified locally". – cypherfox Mar 24 '18 at 11:11