Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ease the replacement of a publication by a new version #341

Closed
llemeurfr opened this issue Nov 22, 2024 · 4 comments · Fixed by #347
Closed

Ease the replacement of a publication by a new version #341

llemeurfr opened this issue Nov 22, 2024 · 4 comments · Fixed by #347

Comments

@llemeurfr
Copy link
Contributor

llemeurfr commented Nov 22, 2024

Sometimes, replacing a publication in the LCP Server with a new version is important. This is especially the case if the publication's accessibility has been corrected. By doing so, users who already have a license for this publication can download the new version after deleting the previous instance from their reading application (note that there is no way with LCP to force a new download of the encrypted content; this is why suppressing the old instance and re-importing the license file in the reading app is required).

The LCP encryption tool has a parameter that allows forcing a content identifier for a newly encrypted publication. The general use case for this feature is to establish a simple relationship between the publication's identification in the ebook provider database and its identification in the LCP Server. It also has a parameter that allows for a specific encryption key, but this parameter has not been documented.

Controlling both the content identifier and encryption key is required for replacing a publication with a new version without breaking existing licenses. Updating the license last modification date is also mandatory, as described in the following use cases:

Use Case 1: A user gets a license for a publication. The publication is then updated with the same id but a different encryption key. The license date is not updated in the server. The user opens the license in a new app.
Consequence: Because the status document does not indicate a license modification, the license is not reloaded. The content is downloaded. The app cannot open a publication encrypted with a different encryption key.

Use Case 2: A user gets a license for a publication. The publication is then updated with the same id and same encryption key. The license date is not updated in the server. The user opens the license in a new app. The app checks the hash and length of encrypted content it downloads.
Consequence: Because the status document does not indicate a license modification, the license is not reloaded. The content is downloaded. The hash and length of the downloaded content are checked, and they do not correspond to the values set in the license. The app cannot open the publication.

Use Case 3: A user gets a license for a publication. The publication is then updated with the same id and same encryption key. The license date is not updated in the server. The user opens the license in a new app. The app does not check the hash and length of encrypted content it downloads.
Consequence: Because the status document does not indicate a license modification, the license is not reloaded. The content is downloaded. The hash and length of the downloaded content are not checked. The app opens the publication.

Use Case 4: A user gets a license for a publication. The publication is then updated with the same id and a different encryption key. The license date is updated. The user opens the license in a new app.
Consequence: Because the status document indicates a license modification, a fresh license is loaded. The content is then downloaded. The encryption key and the publication link in the fresh license correspond to the new encrypted content. The app opens the publication.

Use Case 5: A user gets a license for a publication. The publication is then updated with the same id and a different encryption key. The license date is updated. The user opens the license in the same app.
Consequence: The Status document indicates a change in the license. A fresh license is loaded. It contains a new encryption key and a content hash and length that do not correspond to the content currently stored in the application. The app cannot open the publication because the encryption key in the license does not correspond to the encryption key of the content.

Use Case 6: A user gets a license for a publication. The publication is then updated with the same id and the same encryption key. The license date is updated. The user opens the license in the same app.
Consequence: The Status document indicates a change in the license. A fresh license is loaded. It contains a content hash and length that do not correspond to the content currently stored in the application, but this does not stop the reading application to process the local content as usual (because no file is downloaded, the importance of these attributes is null at this point). The encryption key in the license matches the encryption key of the content. The app opens the publication.

@llemeurfr
Copy link
Contributor Author

llemeurfr commented Nov 22, 2024

LCP providers do not store encryption keys; only the LCP Server has this information. To ease the update of an encrypted publication, we, therefore, enhance the LCP encryption tool so that if a content identifier is passed as a parameter, the code interrogates the license server and retrieves the encryption key used to encrypt the previous instance of the publication.

A new private route must be created in the license server so that retrieving content information becomes feasible (this is a standard REST route), the LCP encryption tool calls it only if a content identifier is passed as a parameter. If the content is not found in the license server, a new encryption key is generated as usual.

When the LCP Server discovers that a publication is replaced, it must also update all licenses attached to this publication, with a new date of update.

@danielweck
Copy link
Member

The hash or length of the content must not be checked

I assume you are referring to LCP license JSON link@rel=publication + @length + @hash? What happens when existing reading systems already verify that link@hash matches the calculated checksum after successfully downloading the referenced resource? Same potential problem with link@length checks ... really, the URL endpoint should be stable whenever returning HTTP response code 200 (i.e. the payload should not vary). The LCP specification doesn't include normative requirements for the processing of hash and length which are optional information fields, but I am concerned about existing implementations that run integrity checks when the fields are provided.

https://readium.org/lcp-specs/releases/lcp/latest.html#35-pointing-to-external-resources-the-links-object

Related issue: readium/lcp-specs#57

@danielweck
Copy link
Member

danielweck commented Nov 28, 2024

EDIT: scrap my comment below, the assumption is that the content key is unchanged, which is important for "user case 4" due to the publication not being downloaded.


In "use case 3":

The license opens the publication because it was encrypted with the same encryption key.

As a fresh license is downloaded, this is irrelevant, isn't it? I mean that the fresh license can contain a different encrypted content key anyway.

@llemeurfr
Copy link
Contributor Author

llemeurfr commented Dec 7, 2024

Hi @danielweck I updated the use cases to be more precise. As a summary, the encryption key must stay the same AND all licenses attached to this publication must be updated. If the two conditions are not met, a problem will arise.

I tried to think about alternative solutions based on HTTP redirect, but did not find anything workable without modifications in the database (that I don't want at this point).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants