Protecting Content: Adobe Flash Access™
Protecting Content: Adobe Flash Access™
Protecting Content: Adobe Flash Access™
Protecting Content
Version 2.0
Contents
About this document................................................................................................................... 5
Who should read this document? ............................................................................................................................................ 5
Conventions used in this document ....................................................................................................................................... 5
Additional information................................................................................................................................................................. 5
Introduction ................................................................................................................................. 7
Usage rules ....................................................................................................................................................................................... 7
User Authentication ................................................................................................................................................................ 7
Expiration.................................................................................................................................................................................... 7
Runtime and application restrictions ............................................................................................................................... 8
Output protection ................................................................................................................................................................... 8
Other policy options ............................................................................................................................................................... 9
Packaging options ......................................................................................................................................................................... 9
Encrypting tracks...................................................................................................................................................................... 9
Encrypting script data ..........................................................................................................................................................10
Other packaging options ....................................................................................................................................................10
Contents
4
Description
brackets [ ]
code italic
Indicates that you should replace the text in code italic with
an actual value.
Additional information
The resources in this table provide additional information about Flash Access SDK.
For information about
See
Overview
Protecting Content
Protecting Content
Additional information
See
Usage Rules
Introduction
Adobe Flash Access is an advanced digital rights management and content protection solution for
high-value audiovisual content. Using tools that you create using Java APIs, you can create policies, apply
policies to files containing audio and video content, and encrypt those files. The high-level steps for
performing these tasks are as follows:
1. Use the Java APIs to set the policy properties and encryption parameters.
2. Create a policy describing the usage roles for the content. (See Working with policies.)
You can create any number of policies. Most users create a small number of policies and apply them to
many files.
3. Package a media file.
In this context, packaging a file means to encrypt it and apply a policy to it. (See Packaging media files.)
4. Implement the license server to issue a license to the user.
The encrypted content is now ready for deployment, and the client can request the license from the server.
The SDK provides a Java API to accomplish these tasks, and includes reference implementations of the
license server, and command line tools that are based on the Java APIs. For information, see Using the
reference implementations.
Note: The architecture allows for usage policies to be specified and bound to content when the content is
packaged. Before a client can play back content, the client must acquire a license for that computer.
The license specifies the usage rules that are enforced and provides the key used to decrypt the
content. The policy is a template for generating the license, but the license server may choose to
override the usage rules when issuing the license. Note that the license may be rendered invalid by
such constraints as expiration times or playback windows.
Usage rules
The following section describes the usage rules that you can specify in a policy.
Authentication
User authentication
Specifies whether a credential, such as username and password, is required to acquire a license. If
authenticated (identity-based) licensing is specified, the server authenticates the user before issuing a
license.
Example use case: A subscription service might require a username/password to be entered before issuing
a content license. A DVD or Blu-ray disc with Digital Copy might provide a code or other token as proof of
payment, which can be redeemed for an electronic download.
Introduction
Time-based rules
Time-based rules
Start date
Specifies the date after which a license is valid.
Example use case: Use an absolute date to issue content licenses ahead of the availability date of an asset,
or to enforce an "embargo" period.
End date
Specifies the date after which a licenses expires.
Example use case: Use an absolute expiration date to reflect the end of distribution rights.
Playback window
Specifies the duration a license is valid after the first time it is used to play protected content.
Example use case: Some business models allow a rental period of 30 days but, once playback begins, it
must be completed in 48 hours. This 48-hour longevity of the license is defined as the playback window.
Introduction
Other policy options
White-list for Adobe Flash Player SWFs allowed to play protected content
New in 2.0: A white list for Adobe Flash Player SWFs allowed to play protected content
Specifies the SWF files that can play content. Specify the SWF file by a SWF URL or a SHA-256 digest
computed using the contents of the SWF. If you use the SHA-256 digest, this usage rule also specifies the
maximum amount of time to allow for the client to download and verify the SWF.
Example use case: Conceptually equivalent to SWF Verification in the case of Flash Media Server, but
enforced on the client side to limit which video players can play the content.
Introduction
Packaging Options
10
application or Flash Player SWF white-list options. For more information, see Runtime and application
restrictions on page 3.
License chaining
New in 2.0: License chaining
Allows a license to be updated using a parent root license for batch updating of licenses.
Example use case: Use this option to update any linked licenses by downloading a single root license. For
example, implement subscription models where content can be played back as long as the user renews
the subscription on a monthly basis. The benefit of this approach is that users only have to do a single
license acquisition to update all of their subscription licenses.
Packaging Options
The following encryption options are selected at packaging time and cannot be modified during license
acquisition.
Encrypting tracks
Specifies which parts of the content are encrypted: audio, video, or both.
Example use case: Permits encrypting just the tracks of the content that require protection, thus reducing
the decryption overhead on the client and improving playback performance.
Introduction
Initial portion of content in the clear
11
These settings were designed with the following rule: Any content that is encrypted at the low setting is
also encrypted at the medium setting. This ensures that the same piece of content distributed at low
encryption by one party and distributed at medium encryption by another party does not compromise
the protection of the content.
Example use case: Reducing the encryption level decreases the decryption overhead on the client and
improves playback performance on low-end machines.
Custom metadata
New in 2.0: Specify custom key/value to add to content metadata that can be interpreted by the
server application.
The Flash Access content metadata format allows for inclusion of custom key/value pairs at packaging
time to be processed by the license server during license issuance. This metadata is separate from the
policy and can be unique for each piece of content.
Example use case: During a Beta phase, you include the custom property "Release:BETA" at packaging
time. License servers can vend licenses to this content during the Beta period, but after the Beta period
expires, the license servers disallow access to the content.
Introduction
Multiple policies
12
Multiple policies
Specify multiple policies to be associated with a single piece of content. The specific policy to be used is
determined by the license server.
Example use case: If the same asset is used for both electronic sell-through and rental models, this option
allows you to specify different sets of usage rules for each business model. The license server can choose
which policy to use based on whether the customer purchased or rented the content.
Output protection
Output protection controls
New in 2.0: Control whether output to external rendering devices is protected. Specify analog
and digital outputs independently.
Controls whether output to external rendering devices should be restricted. An external device is defined
as any video or audio device that is not embedded in the computer. The list of external devices excludes
integrated displays, such as in notebook computers. Analog and digital output restrictions can be
specified independently.
The following options/levels of enforcement are available:
Note: While these rules are consistently enforced across all platforms, currently it is only possible to
securely turn on output protection on Windows platforms. On other platforms (such as Macintosh
and Linux) there are no supporting operating system functions available to third party applications.
Example use case: Some content might enforce output protection controls, and the level of protection can
be set by the content distributor. If "Required" is specified and playback is attempted on a Macintosh, the
client does not play back content on external devices. The content will, however, play back on internal
monitors.
If "Required" is specified and playback is attempted on Linux, the client does not play back content on any
devices because it is not possible to differentiate between internal and external devices.
If you specify "Use if available", output protection is turned on where possible. For example, on Windows
machines that support the Certified Output Protection Protocol (COPP), the content is passed with output
protection to an external display. This example is sometimes known as "selectable output control".
You need the following third party JAR files also located on the DVD in the SDK's "thirdparty" folder:
bcmail-jdk15-141.jar
bcprov-jdk15-141.jar
commons-discovery-0.4.jar
commons-logging-1.1.1.jar
jaxb-api.jar
jaxb-impl.jar
jaxb-libs.jar
relaxngDatatype.jar
rm-pdrl.jar
xsdlib.jar
You also need one of the JAR files in the "thirdparty/jsafe" folder. jsafe.jar is the pure-Java version.
Alternatively, you can use jsafeWithNative.jar, which has better performance, but also requires that
platform specific libraries (for example, jsafe.dll for Windows or libjsafe.so for Linux) be added to the path.
Additionally, an optional part of the SDK is adobe-flashaccess-lcrm.jar. This file is only needed for
functionality related to 1.x compatibility. If you previously deployed Adobe Flash Media
Rights Management Server 1.x, you must add support to your license server so it will be able to handle old
content and clients.
Requesting certificates
There are three types of credentials required to use Flash Access:
Packager: used during packaging to sign the metadata added to the encrypted content
License Server: used to protect the content encryption key in the metadata, and used by the license
server to sign licenses
Transport: used to protect requests/responses exchanged between the client and the license server
11
12
Enrollment is the process of requesting a certificate from Adobe. You can generate your keys and create a
request that is sent to Adobe. Adobe then generates the certificate and sends it back to you. Adobe will
not know the contents of the private key. Therefore, you must have a way to back up the key so that you
can recover it in case of hardware failure.
You can keep a private key on a Hardware Security Module (HSM) and use the SDK to pass in the credential
you obtain from the HSM. To use a credential stored on an HSM, use a JCE provider that can communicate
with an HSM to get a handle to the private key. Then, pass the private key handle, provider name, and
certificate containing the public key to ServerCredentialFactory.getServerCredential().
The SunPKCS11 provider is one example of a JCE provider which can be used to access a private key on an
HSM (see the Sun Java documentation for instructions on using this provider). Some HSMs also come with
a Java SDK which includes a JCE provider.
The SDK supports multiple ways of storing credentials, including on an HSM or as a PKCS12 file. PKCS12 is
a standard format for a file containing a credential (a public key certificate and its associated private key)
encrypted using a password. PFX is the file extension commonly used for files of this format.
Credentials are used when the private key is required (for example, for the packager to sign the metadata,
or for the license server to decrypt data encrypted with the license server or transport public key). Private
keys must be closely guarded to ensure the security of your content and license server.
Adobe recommends using an HSM for maximum security. For more information, see Secure Deployment
Guidelines.
PEM and DER are two ways of encoding a public key certificate. PEM is a base-64 encoding and DER is a
binary encoding. Certificate files typically use the extension .cer, .pem. or .der. Certificates are used in
places where only the public key is required. If a component requires only the public key to operate, it is
better to provide that component with the certificate instead of a credential or PKCS12 file.
For instructions on how to obtain the Flash Access credentials, see the Certificate Enrollment Guide.
In addition to these operations, it is possible to create a policy update list that does not require that
content be repackaged after a policy is updated. For more information, see Packaging media files.
For details about the Java API discussed in this chapter, see Adobe Flash Access API Reference.
For information about the Policy Manager reference implementation, see Using the reference
implementations.
13
Protecting Content
14
com.adobe.flashaccess.sdk.policy.LicenseServerInfo;
com.adobe.flashaccess.sdk.policy.Policy;
com.adobe.flashaccess.sdk.policy.PolicyException;
com.adobe.flashaccess.sdk.policy.ServerInfo.AuthenticationType;
com.adobe.flashaccess.sdk.rights.PlayRight;
com.adobe.flashaccess.sdk.rights.Right;
import
import
import
import
import
import
java.io.FileOutputStream;
java.io.IOException;
java.text.ParseException;
java.text.SimpleDateFormat;
java.util.ArrayList;
java.util.List;
/**
* Demonstrates policy creation.
*/
public class CreatePolicy
{
public static void main(String[] args) {
// Create a new Policy object.
// False indicates the policy does not use license chaining.
Policy policy = new Policy(false);
policy.setName("DemoPolicy");
// Specify that the policy requires authentication to obtain a license.
policy.setLicenseServerInfo(new
LicenseServerInfo(AuthenticationType.UsernamePassword));
// A policy must have at least one Right, typically the play right
PlayRight play = new PlayRight();
Protecting Content
15
Protecting Content
16
3. Update the Policy object by setting its properties, such as its name.
4. Serialize the updated Policy object and store it in a file or database.
The following Java file shows how to update a policy.
com.adobe.flashaccess.sdk.policy.Policy;
com.adobe.flashaccess.sdk.policy.PolicyException;
com.adobe.flashaccess.sdk.rights.ModuleRequirements;
com.adobe.flashaccess.sdk.rights.PlayRight;
com.adobe.flashaccess.sdk.rights.Right;
com.adobe.flashaccess.sdk.util.VersionInfo;
import
import
import
import
import
import
java.io.File;
java.io.FileInputStream;
java.io.FileOutputStream;
java.io.IOException;
java.util.ArrayList;
java.util.Collection;
/**
* Demonstrates updating an existing policy.
*/
public class UpdatePolicy
{
public static void main(String[] args) {
// Specify the name of the file containing the policy.
String policyFile = "demopolicy.pol";
// Read the policy from the file.
Policy policy = null;
try {
policy = readPolicyFromFile(new File(policyFile));
} catch (PolicyException e) {
// File contains an invalid policy
e.printStackTrace();
} catch (IOException e) {
// Error reading policy from file
e.printStackTrace();
Protecting Content
17
}
if (policy == null)
return;
System.out.println("Updating policy with ID: " + policy.getId() +
" and revision: " + policy.getRevision());
// Change the policy name.
policy.setName("UpdatedDemoPolicy");
// Add DRM module restrictions to the play right
for (Right r: policy.getRights()) {
if (r instanceof PlayRight) {
PlayRight pr = (PlayRight) r;
// Disallow Linux versions up to and including 1.9. Allow
// all other OSes and Linux versions above 1.9
VersionInfo toExclude = new VersionInfo();
toExclude.setOS("Linux");
toExclude.setReleaseVersion("1.9");
Collection<VersionInfo> exclusions = new ArrayList<VersionInfo>();
exclusions.add(toExclude);
ModuleRequirements drmRestrictions = new ModuleRequirements();
drmRestrictions.setExcludedVersions(exclusions);
pr.setDRMModuleRequirements(drmRestrictions);
break;
}
}
try
{
// Serialize the policy.
byte[] policyBytes = policy.getBytes();
System.out.println("New policy revision number: " +
policy.getRevision());
// Write the policy to a file.
// Alternatively, the policy may be stored in a database.
FileOutputStream out = new FileOutputStream("demopolicy-updated.pol");
out.write(policyBytes);
out.close();
} catch (PolicyException e) {
// The policy could not be created, because required fields were not
set.
e.printStackTrace();
} catch (IOException e) {
// Error writing policy to file
e.printStackTrace();
}
}
private static Policy readPolicyFromFile(File policyFile) throws
IOException, PolicyException {
FileInputStream in = null;
try {
in = new FileInputStream(policyFile);
18
parameters, as well as indicate whether to encrypt audio content, video content, or script data. To see how
these are implemented in the reference implementation, see the descriptions of the command line
options discussed in Policy Manager. These options are based on the Java API and are therefore available
for programmatic usage.
The packaging options include:
Encryption options (audio, video, partial encryption). For more information on encryption options, see
Packaging options on page 9.
License server URL (the client uses this as the base URL for all requests sent to the license server)
Flash Access provides an API for passing in the CEK. If no CEK is specified, the SDK randomly generates it.
Typically you need a different CEK for each piece of content. However, in Dynamic Streaming, you would
likely use the same CEK for all the files for that content, so the user only needs a single license and can
seamlessly transition from one bit rate to another. To use the same key and license for multiple pieces of
content, pass the same DRMParameters object to MediaEncrypter.encryptContent(), or pass in
the CEK using V2KeyParameters.setContentEncryptionKey. To use a different key and license for
each piece of content, create a new DRMParameters instance for each file.
In some cases you may need to store the content metadata as a separate file and make it available to the
client separate from the content. To do this, invoke MediaEncrypter.encryptContent(), which
returns a MediaEncrypterResult object. Call MediaEncrypterResult.getKeyInfo() and cast
the result to V2KeyStatus. Then retrieve the content metadata and store it in a file.
19
20
All of these tasks can be accomplished using the Java API. For details about the Java API discussed in this
chapter, see Adobe Flash Access API Reference.
For information about the Media Packager reference implementation, see Using the reference
implementations.
Encrypting content
Encrypting FLV and F4V content involves the use of a MediaEncrypter object. You can also package FLV
and F4V files that contain only audio tracks. When encrypting H.264 content for lower-end devices, it may
be practical to apply only partial encryption to improve performance. In such cases, an F4V file may be
partially encrypted using the F4VDRMParameters.setVideoEncryptionLevel method.
To encrypt an FLV or an F4V file by using the Java API, perform the following steps:
1. Set up your development environment and include all of the JAR files mentioned in Setting up the
development environment within your project.
2. Create a ServerCredential instance to load the credentials needed for signing.
3. Create a MediaEncrypter instance. Use a MediaEncryperFactory if you do not know what type
of file you have. Otherwise you can create an FLVEncrypter or F4VEncrypter directly.
4. Specify the encryption options by using a DRMParameters object.
5. Set the signature options using a SignatureParameters object and pass the ServerCredential
instance to its setServerCredentials method.
6. Set the key and license information using an V2KeyParameters object. Set the policies using the
setPolicies method. Set the information needed by the client to contact the license server by
calling the setLicenseServerUrl and setLicenseServerTransportCertificate methods.
Set the CEK encryption options using the setKeyProtectionOptions method, and its custom
properties using the setCustomProperties method. Finally, depending on the type of encryption
used, cast the FMRMSKeyParameters object to one of VideoDRMParameters,
AudioDRMParameters, FLVDRMParameters, or F4VDRMParameters, and set the encryption
options.
7. Encrypt the content by passing the input and output files and encryption options to the
MediaEncrypter.encryptContent method.
The following Java file shows how to encrypt a FLV file.
Protecting Content
Encrypting content
21
Protecting Content
Encrypting content
22
Protecting Content
Encrypting content
23
keyParams.setLicenseServerUrl(licenseServerUrl);
keyParams.setContentId(contentID);
// Set the policies.
Policy[] policies = new Policy[1];
policies[0] = loadPolicy(policyFile);
keyParams.setPolicies(policies);
// Set the transport certificate for the license server
keyParams.setLicenseServerTransportCertificate(loadCert(tranportServerCertif
icateFile));
// Set the key options. An encrypted key means the content key is
encrypted
// using the license server's public key.
AsymmetricKeyProtectionOptions keyOpts = new
AsymmetricKeyProtectionOptions (
loadCert(licenseServerCertificateFile)
);
keyParams.setKeyProtectionOptions(keyOpts);
// Add custom properties.
ApplicationProperties customProps = new ApplicationProperties();
customProps.addUTF8String("My Custom Property", "Property Value");
keyParams.setCustomProperties(customProps);
params.setKeyParameters(keyParams);
// Specify the type of encryption to be used.
if (params instanceof VideoDRMParameters) {
((VideoDRMParameters) params).setEncryptVideo(encryptVideo);
}
if (params instanceof AudioDRMParameters) {
((AudioDRMParameters) params).setEncryptAudio(encryptAudio);
}
if (params instanceof FLVDRMParameters) {
((FLVDRMParameters) params).setEncryptScript(encryptScript);
}
if (params instanceof F4VDRMParameters) {
// Change to Medium or Low to enable partial encryption of H.264
content
((F4VDRMParameters)
params).setVideoEncryptionLevel(F4VDRMParameters.EncryptionLevel.High);
}
// Encrypt the content,
MediaEncrypterResult result = encrypter.encryptContent(inputFile,
outputFile, params);
// Display the results,
if (result.hasWarnings()) {
System.out.println("Media Packaging Finished with warnings");
for (WarningMessage warn : result.getWarnings()) {
System.out.println("WARNING: " + warn.getMessage());
}
Protecting Content
24
} else {
System.out.println("Media Packaging Successful");
}
catch (CredentialException e) {
e.printStackTrace();
System.err.println("Failed to load signing credential");
catch (UnknownMediaException e) {
e.printStackTrace();
System.err.println("Unable to determine file type");
catch (IOException e) {
e.printStackTrace();
System.err.println("Error opening file");
catch (KeyRetrievalException e) {
e.printStackTrace();
System.err.println("Unable to get key from server");
catch (Exception e) {
e.printStackTrace();
System.err.println("Error: " + e.getMessage());
}
}
private static Policy loadPolicy(File policyFile) throws IOException,
PolicyException {
FileInputStream in = null;
try {
in = new FileInputStream(policyFile);
byte[] polBuf = new byte[ (int) policyFile.length() ];
in.read( polBuf );
return new Policy(polBuf);
} finally {
if (in != null)
in.close();
}
}
public static X509Certificate loadCert(File certFile) throws IOException {
FileInputStream in = null;
try {
in = new FileInputStream(certFile);
return CertificateFactory.loadCert(in);
} catch (CertificateException e) {
throw new IOException("Unable to load license server certificate");
} finally {
if (in != null)
in.close();
}
}
}
Protecting Content
25
1. Set up your development environment and include all of the JAR files mentioned in Setting up the
development environment within your project.
2. Create a MediaEncrypter instance.
3. Pass the encrypted file to the MediaEncrypter.examineEncryptedContent method, which
returns a KeyMetaData object.
4. Inspect the information within the KeyMetaData object.
The following Java file shows how to examine the content of an encrypted FLV file.
com.adobe.flashaccess.sdk.media.drm.MediaEncrypter;
com.adobe.flashaccess.sdk.media.drm.format.flv.FLVEncrypter;
com.adobe.flashaccess.sdk.media.drm.keys.KeyMetaData;
com.adobe.flashaccess.sdk.media.drm.keys.v2.V2KeyMetaData;
import java.io.*;
/**
* Demonstrates examining an FLV or F4V that was previously packaged.
*/
public class ExamineContent {
public static void main(String[] args) {
// Location of encrypted file
File encryptedFile = new File("C:/encryptedsamplevideo.flv");
// Get a MediaEncrypter.
MediaEncrypter encrypter = new FLVEncrypter();
try {
// Get information about the key
KeyMetaData keyInfo =
encrypter.examineEncryptedContent(encryptedFile);
if (keyInfo == null) {
System.out.println("Unable to find encryption metadata in file");
} else if (keyInfo instanceof FMRMSKeyMetaData) {
V2KeyMetaData metadata = (V2KeyMetaData)keyInfo;
System.out.println("License ID: " +
metadata.getContentMetadata().getLicenseId());
Protecting Content
}
} catch (IOException e) {
e.printStackTrace();
System.err.println("Error reading file");
}
}
}
26
In addition, the server needs to provide business logic for authenticating users, determining if users are
authorized to view content, and optionally track license usage.
For details about the Java API discussed in this chapter, see Adobe Flash Access API Reference.
information in the request and decide whether to return an error or a successful response (subclasses of
RequestMessageBase provide a method for setting response data).
If the request is successful, set the response data; otherwise invoke
RequestMessageBase.setErrorData() on failure. Always end the implementation by invoking the
close() method (it is recommended that close() be called in the finally block of a try statement).
See the MessageHandlerBase API reference documentation for an example of how to invoke the
handler.
Note: HTTP status code 200 (OK) should be sent in response to all requests processed by the handler. If
the handler could not be created due to a server error, the server may respond with another status
code, such as 500 (Internal Server Error).
For replay protection, it may be prudent to check whether the message identifier has been seen recently
by calling RequestMessageBase.getMessageId(). If so, an attacker may be trying to replay the
request, which should be denied. To detect replay attempts, the server can store a list of recently seen
message ids and check each incoming request against the cached list. To limit the amount of time the
message identifiers need to be stored, call HandlerConfiguration.setTimestampTolerance(). If
this property is set, the SDK will deny any request that carries a timestamp more than the specified
number of seconds off the server time.
For rollback detection, some usage rules require the client to maintain state information for enforcement
of the rights. For example, to enforce the playback window usage rule, the client stores the date and time
when the user first began viewing the content. This event triggers the start of the playback window. To
securely enforce the playback window, the server needs to ensure that the user is not backing up and
restoring the client state in order to remove the playback window start time stored on the client. The
server does this by tracking the value of the client's rollback counter. For each request, the server gets the
27
28
29
authentication token is sent in subsequent requests. See Handling license requests below for information
on handling custom authentication tokens.
The handler reads an authentication request and parses the request message when parseRequest() is
called. The server implementation examines the user credentials in the request, and if the credentials are
valid, generates an AuthenticationToken object by calling
getRequest().generateAuthToken(). If
AuthenticationRequestMessage.generateAuthToken() is not called before close(), an
authentication failure error code is sent.
The request URL is constructed as follows: "License Server URL in the metadata" + "/flashaccess/authn/v1".
See the AuthenticationHandler API reference documentation for an example of how to invoke the
handler.
Protecting Content
Authentication
30
exception also includes ErrorData to be returned to the client. See the API documentation for
LicenseRequestMessage.generateLicense() for details on how policies are evaluated during
license generation.
The client can send a license preview request, meaning that the application can carry out a preview
operation before asking the user to buy the content in order to determine whether the user's machine
actually meets all the criteria required for playback. License preview refers to the client's ability to preview
the license (to see what rights the license allows) as opposed to previewing the content (viewing a small
portion of the content before deciding to buy). Some of the parameters that are unique to each machine
are: outputs available and their protection status, the runtime/DRM version available, and the DRM client
security level. The license preview mode allows the runtime/DRM client to test the license server business
logic and provide information back to the user so he can make an informed decision. Thus the client can
see what a valid license looks like but would not actually receive the key to decrypt the content. Support
for license preview is optional, and only necessary if you implement a custom client that uses this
functionality.
The request URL is constructed as follows: "License Server URL in the metadata" + "/flashaccess/license/v1".
If identity-based licensing is used, the server checks for a valid authentication token before issuing a
license.
Note: To preview a license for identity-based content, a client must authenticate.
To determine whether the client sent a preview request or license acquisition request, call
LicenseRequestMessage.getRequestPhase()and compare it to
LicenseRequestMessage.RequestPhase.Acquire.
Licenses and errors are sent at one time when LicenseHandler.close() is called.
Authentication
A license request can contain an authentication token. If username/password authentication was used, the
request may contain an AuthenticationToken generated by the AuthenticationHandler, and the
SDK will check if the token is valid.
If the client and server are using a custom authentication mechanism, the client obtains an authentication
token through some other channel and passes the token into the client APIs. Use
RequestMessageBase.getRawAuthenticationToken() to get the custom authentication token
and implement the logic to check that the token is valid.
Updating policies
If policies are updated after the content is packaged, provide the updated policies to the license server so
the updated version can be used when issuing a license. If your license server has access to a database for
storing policies, you can retrieve the updated policy from the database and call
LicenseRequestMessage.setSelectedPolicy() to provide the new version of the policy.
For license servers that do not rely on a central database, the SDK provides support for Policy Update Lists.
A policy update list is a file containing a list of updated or revoked policies. When a policy is updated,
generate a new Policy Update List and periodically push the list out to all the license servers. Pass the list to
the SDK by setting HandlerConfiguration.setPolicyUpdateList(). If an update list is provided,
the SDK consults this list when parsing the content metadata. ContentInfo.getUpdatedPolicies()
contains the updated versions of policies specified in the metadata.
31
Upgrading clients
If an FMRMS 1.x client contacts a Flash Access 2.0 server, the server needs to prompt the client to upgrade.
This is achieved using
com.adobe.flashaccess.sdk.protocol.compatibility.FMRMSv1RequestHandler. Unlike
other Flash Access request handlers, this handler does not provide access to any request information or
require any response data to be set. Create an instance of the FMRMSv1RequestHandler, and then call
close().
The request URL is constructed as follows: Base URL from 1.x content" +
"/edcws/services/urn:EDCLicenseService".
Upgrading metadata
If a 2.0 client encounters content packaged with Flash Media Rights Management Server 1.x, it will extract
the encryption metadata from the content and send it to the server. The server will convert the 1.x
metadata into the 2.0 format and send it back to the client. The client then sends the updated metadata in
a standard 2.0 license request. The FMRMSv1MetadataHandler class is involved in processing these
requests.
The request URL is constructed as follows: "Base URL from 1.x content" +
"/flashaccess/headerconversion/v1".
This conversion could be done on the fly when the server receives the old metadata from the client.
Alternatively, the server could preprocess the old content and store the converted metadata; in this case,
Protecting Content
32
when the client requests new metadata, the server just needs to fetch the new metadata matching the
license identifier of the old metadata.
To convert metadata, the server must perform the following steps:
Get the license identifier from the old metadata, and find the encryption key and policies (this
information was originally in the Adobe LiveCycle ES database. The LiveCycle ES policies must be
converted to Flash Access 2.0 policies.) The Reference Implementation includes scripts and sample
code for converting the policies and exporting license information from LiveCycle ES.
Load the SigningCredential, which is the packager credential issued by Adobe used to sign
encryption metadata. Get the SignatureParameters object by calling
MediaEncrypter.getSignatureParameters() and fill in the signing credential.
2. (Optional) Once the policy update list or revocation list has been re-signed, you can add new entries to
the list using the command line tools or API, making sure to sign with the new credentials.
For example, use the following command line to add an entry to an existing policy update list:
java -jar AdobePolicyUpdateListManager.jar newList -f oldList -u pol 0 "" ""
3. Use the Java API to update the license server with the new policy update list or revocation list:
Protecting Content
Performance tuning
33
HandlerConfiguration.setRevocationList
or:
HandlerConfiguration.setPolicyUpdateList
Ensure that the current credential is passed into the LicenseHandler constructor:
In the Flash Access Server for protected streaming, the current credential must be the first
credential specified in the LicenseServerCredential element in the
flashaccess-tenant.xml file.
Ensure that the current and old credentials are provided to AsymmetricKeyRetrieval
In the Flash Access Server for protected streaming, the old credentials are specified after the first
credential in the LicenseServerCredential element in the flashaccess-tenant.xml file.
In the Flash Access Server for protected streaming, the current credential must be the first
credential specified in the TransportCredential element in the flashaccess-tenant.xml file.
In the Flash Access Server for protected streaming, this is specified after the first credential in the
TransportCredential element in the flashaccess-tenant.xml file.
5. Update packaging tools to make sure they are packaging content with the current credentials. Ensure
that the latest license server certificate, transport certificate, and packager credential are used for
packaging.
Performance tuning
Use the following tips to help to increase performance:
Using a network HSM can be significantly slower than using a directly-connected HSM.
Protecting Content
Performance tuning
You can one of the JAR files in the "thirdparty/jsafe" folder. jsafe.jar is the pure-Java version.
Alternatively, you can use jsafeWithNative.jar, which has better performance, but also requires that
platform specific libraries (for example, jsafe.dll for Microsoft Windows or libjsafe.so for Linux) be
added to the path.
A 64-bit operating system, such as the 64-bit version of Red Hat or Windows, provides much better
performance over a 32-bit operating system.
Note: If you use a 64-bit version of Windows, HSM is currently not supported.
34
35
36
Protecting Content
37
4. Specify the issuer and serial number of the machine token to be revoked by using a
IssuerAndSerialNumber object. All authentication and license requests contain a machine token.
5. Create a RevocationList object using the IssuerAndSerialNumber object you just created, and
add it to the revocation list by passing it into
RevocationListFactory.addRevocationEntry(). Generate the new revocation list by calling
RevocationListFactory.generateRevocationList().
6. To save the revocation list, you can serialize it by calling RevocationList.getBytes(). To load the
list, call RevocationListFactory.loadRevocationList() and pass in the serialized list.
7. Verify that the signature is valid and the list was signed by the correct license server by calling
RevocationList.verifySignature().
8. To check whether an entry was revoked, pass the IssuerAndSerialNumber object into
RevocationList.isRevoked(). The revocation list may also be passed into
HandlerConfiguration to have the SDK enforce the revocation list for all authentication and
license requests.
To add additional entries to an existing RevocationList, load an existing revocation list. Create a new
RevocationListFactory instance, and be sure to increment the CRL number. Call
RevocationListFactioryEntries.addRevocationEntries to add all the entries from the old list
to the new list. Call RevocationListFactory.addRevocationEntry to add any new revocation
entries to the RevocationList.
The following Java file shows how to create a revocation list, load an existing revocation list, and check
whether a machine token has been revoked.
Example: Creating and parsing a revocation list using the Java API
/*************************************************************************
*
* ADOBE SYSTEMS INCORPORATED
* Copyright 2009 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: Adobe permits you to use, modify, and distribute this file in
* accordance with the terms of the Adobe license agreement accompanying it.
* If you have received this file from a source other than Adobe, then your use,
* modification, or distribution of it requires the prior written permission of
* Adobe.
**************************************************************************/
package com.adobe.fmrms.samples.revocation;
import
import
import
import
java.io.ByteArrayInputStream;
java.io.File;
java.math.BigInteger;
java.util.Date;
import
import
import
import
import
import
com.adobe.flashaccess.sdk.cert.IssuerAndSerialNumber;
com.adobe.flashaccess.sdk.cert.ServerCredential;
com.adobe.flashaccess.sdk.cert.ServerCredentialException;
com.adobe.flashaccess.sdk.cert.ServerCredentialFactory;
com.adobe.flashaccess.sdk.revocation.RevocationEntry;
com.adobe.flashaccess.sdk.revocation.RevocationException;
Protecting Content
38
import com.adobe.flashaccess.sdk.revocation.RevocationList;
import com.adobe.flashaccess.sdk.revocation.RevocationListFactory;
/**
* Demonstrates how to create a revocation list,
* how to load an existing revocation list,
* and how to check if a machine token has been revoked.
*/
public class CreateRevocationList
{
public static void main( String args[] )
{
// Specify the file containing the license server credentials issued by
Adobe.
// These credentials are used to sign the revocation list.
File licSvrCredentialFile = new File("C:/licenseServerCredentials.pfx");
// Set the password needed to open the certificate file.
String licSvrCredentialPassword = "password";
try {
// Load the credential for signing.
ServerCredential signingCred =
ServerCredentialFactory.getServerCredential(
licSvrCredentialFile,
licSvrCredentialPassword
);
RevocationListFactory rlFactory = new RevocationListFactory(
signingCred,
1
);
// Set the issuer and serial number of the machine token to be revoked.
IssuerAndSerialNumber toRevoke = new
IssuerAndSerialNumber("E=*.adobe.com", BigInteger.valueOf(1));
// Create the revocation entry and add it to the revocation list that
will be generated.
RevocationEntry crlEntry = new RevocationEntry(toRevoke, new Date());
rlFactory.addRevocationEntry(crlEntry);
// Generate the new revocation list.
RevocationList newRevList = rlFactory.generateRevocationList();
// Serialize the revocation list.
byte[] revListBytes = newRevList.getBytes();
// Given a revocation list, verify its signature.
RevocationList revList = RevocationListFactory.loadRevocationList(new
ByteArrayInputStream(revListBytes));
revList.verifySignature(signingCred.getCertificate());
// Check if the entry was revoked.
boolean isRevoked = revList.isRevoked(toRevoke);
Protecting Content
39
} catch (ServerCredentialException e) {
// There was a problem loading the license server credential.
e.printStackTrace();
} catch (RevocationException e) {
// There was a problem creating or reading the revocation list.
e.printStackTrace();
}
}
}
Protecting Content
40
The following Java file shows how to create a policy update list, load an existing policy update list, and
check whether a policy has been revoked.
Example: Creating and parsing a policy update list using the Java API
/*************************************************************************
*
* ADOBE SYSTEMS INCORPORATED
* Copyright 2009 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: Adobe permits you to use, modify, and distribute this file in
* accordance with the terms of the Adobe license agreement accompanying it.
* If you have received this file from a source other than Adobe, then your use,
* modification, or distribution of it requires the prior written permission of
* Adobe.
**************************************************************************/
package com.adobe.fmrms.samples.policyupdatelist;
import
import
import
import
import
import
import
com.adobe.flashaccess.sdk.cert.ServerCredential;
com.adobe.flashaccess.sdk.cert.ServerCredentialException;
com.adobe.flashaccess.sdk.cert.ServerCredentialFactory;
com.adobe.flashaccess.sdk.policyupdate.PolicyRevocationEntry;
com.adobe.flashaccess.sdk.policyupdate.PolicyUpdateList;
com.adobe.flashaccess.sdk.policyupdate.PolicyUpdateListException;
com.adobe.flashaccess.sdk.policyupdate.PolicyUpdateListFactory;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.Date;
/**
* Demonstrates how to create a policy update list,
* how to load an existing policy update list,
* and how to check if a policy has been updated or revoked.
*/
public class CreatePolicyUpdateList
{
public static void main( String args[] )
{
// Specify the file containing the license server credentials issued by
Adobe.
// These credentials are used to sign the policy update list.
File licSvrCredentialFile = new File("C:/licenseServerCredentials.pfx");
// Set the password needed to open the certificate file.
String licSvrCredentialPassword = "password";
try {
// Load the credential for signing.
ServerCredential signingCred =
ServerCredentialFactory.getServerCredential(
licSvrCredentialFile,
licSvrCredentialPassword
);
Protecting Content
41
42
Usage rules
With the Flash Access Server for Protected Streaming, all usage rules are specified on the server through
configuration files. Any usage rules specified in the protected content are ignored, so it is recommended
to use a simple anonymous policy during content packaging. Usage rules that are configurable can be set
on a per-tenant basis.
The Flash Access Server for Protected Streaming supports the following usage rules:
Output Protection
License Caching is disabled by default. License caching can be enabled by specifying the caching end
date or an amount of time caching is allowed (starting when the license is issued).
Multiple Play Rights, which lets you specify different combinations of Output Protection, Application
Restrictions, and DRM/Runtime Restrictions. For example, it is possible to specify different Output
Protection requirements for each client platform by using the DRM Module Restriction with Output
Protection.
Anonymous access
Licenses are valid for 24 hours, starting when the license is issued
Requirements
Java JRE 1.6 (Java JDK 1.6 is required to create custom authorization extensions)
43
Flash Access Server for Protected Streaming (Available in the Flash Access Server for Protected
Streaming folder on the DVD)
44
LicenseServer.ConfigRoot Directory containing all the configuration files for the license server. For
details on the contents of these files, see License server configuration files on page 45. If not set, the
default is CATALINA_BASE/licenseserver.
LicenseServer.LogRoot Directory of the "logs" folder, where license server application logs are
written. If not set, the default is LicenseServer.ConfigRoot.
If you are using catalina.bat or catalina.sh to start Tomcat, these System properties can easily be set using
the JAVA_OPTS environment variable. Any Java options set here will be used when Tomcat is started. For
example, set:
JAVA_OPTS=-DLicenseServer.ConfigRoot="absolute-path-to-config-folder"
-DLicenseServer.LogRoot="absolute-path-to-log-folder"
Protecting Content
HSM configuration
45
HSM configuration
If you choose to use an HSM to store your server credentials, you must load the private keys and
certificates onto the HSM and create a pkcs11.cfg configuration file. This file must be located in the
LicenseServer.ConfigRoot directory. See the configs directory for an example PKCS11 configuration file. For
information on the format of pkcs11.cfg, see the Sun PKCS11 provider documentation.
To verify that your HSM and Sun PKCS11 configuration file are configured properly, you can use the
following command from the directory where the pkcs11.cfg file is located (keytool is installed with the
Java JRE and JDK):
keytool -keystore NONE -storetype PKCS11
-providerClass sun.security.pkcs11.SunPKCS11 -providerArg pkcs11.cfg -list
If you see your credentials in the list, the HSM is configured properly and the license server will be able to
access the credentials.
Caching Controls caching of config files in memory. For an explanation of the caching settings, see
Updating configuration files on page 49.
Protecting Content
Logging Specifies the logging level and how frequently log files are rolled.
46
See the comments in the example global configuration file for more details.
Transport Credential Specifies one or more transport credentials (certificate and private key) issued
by Adobe. Can be specified as a path to a .pfx file and a password, or an alias for a credential stored on
an HSM. Several such credentials can be specified here, either as file paths, or key aliases, or both. See
Handling certificate updates on page 32 for more information on when additional credentials are
needed.
License Server Credential Specifies one or more license server credentials (certificate and private
key) issued by Adobe. Can be specified as a path to a .pfx file and a password, or an alias for a credential
stored on an HSM. Several such credentials can be specified here, either as file paths, or key aliases, or
both. See Handling certificate updates on page 32 for more information on when additional
credentials are needed.
Custom Authorizers Optional. Specifies custom authorizer classes to invoke for each license request.
If multiple authorizers are specified, they are invoked in the order listed. For more information, see
Custom authorization extensions on page 47.
Usage Rules
License Caching Optional. Specifies how long the license can be stored on the client. By default
license caching is disabled. To enable license caching for a limited time period, set the end date or
the number of seconds for which the license should be stored (starting when the license is issued).
Setting the number of seconds to 0 disables license caching.
Note that all licenses issued by the protected streaming license server have an expiration period of
24 hours (86400 seconds). This value therefore applies implicitly as an upper bound to whatever
end date or duration is set for license caching as well, with a maximum value of 86400 seconds,
even though the schema enforces higher bounds.
Play Right At least one right must be specified. If multiple rights are specified, the client will use
the first right for which it meets all the requirements.
AIR and SWF Application Restrictions Optional whitelist of SWF and AIR applications that may
play the content (i.e. only the applications specified are permitted). SWF applications are
identified by a URL or by the digest of the SWF and the maximum time to allow for download
Protecting Content
47
and verification of the digest. For information on calculating the SWF digest, see the SWF Hash
Calculator section of Flash Access Server Utilities. AIR applications are identified by a publisher
ID and optional application ID, minimum version, and maximum version. If no application
restrictions are specified, any SWF or AIR application may play the content.
DRM and Runtime Module Restrictions Specifies the minimum security level required for the
DRM/Runtime module. Optionally includes a blacklist of versions that are not permitted to play
the content. Module versions are identified by attributes such as operating system and/or a
version number.
See the comments in the example tenant configuration file for more details.
Performance tuning
This section outlines performance-related considerations.
Protecting Content
48
<Caching>
The <Caching> element controls caching of configuration files in memory. The <Caching> element
has the following syntax:
<Caching refreshDelaySeconds="..." numTenants="..."/>
refreshDelaySeconds controls how often the server checks for updates to the configuration
files. A low value for refreshDelaySeconds negatively impacts performance, while a higher
value can improve performance. For more information on refreshDelaySeconds, see Updating
numTenants specifies the number of tenants. A value that is lower than the number of tenants
likely impacts performance because requests to the remaining tenants result in cache misses. A
cache miss for configuration data negativley impacts performance. Therefore, Adobe recommends
that you set this value higher than the number of tenants configured for the server, unless there are
memory limitations to consider.
<Logging>
The <Logging> element specifies the logging level and how frequently log files are rolled. The
<Logging> element has the following syntax:
<Logging level="..." rollingFrequency=""/>
level specifies the messages to log. A value of "DEBUG" yields a lot of log messages, and can
negatively impact performance. Adobe recommends a setting of "WARN" for optimal performance.
However, that value does risk losing essential runtime information, such as license audits. To
preserve valuable log information with minimal performance impact, use a value of "INFO".
rollingFrequency specifies how often log files are rolled. Rolling is the process where a new log
file becomes the active log, while the previously active log file is no longer written to and is
considered rolled. The rolling interval can be set to "MINUTELY", "HOURLY", "TWICE-DAILY", "DAILY",
"WEEKLY", "MONTHLY", or "NEVER".
49
After the server has started, verify that it is configured properly by opening
http://license-server-host:port/flashaccessserver/tenant-name/flashaccess/license/v1 in a browser
window. If the tenant configuration was successfully loaded, a confirmation message is displayed.
Log files
The log files generated by the Flash Access Server for Protected Streaming application will be located in
the directory specified by LicenseServer.LogRoot. Note: if the current log files are deleted or moved while
the server is running, the log file may not be re-created, and some log information will be lost.
Protecting Content
Packaging content
50
To control how often the server checks for updates, set the "refreshDelaySeconds" attribute in the Caching
element of the global configuration file. For example, if "refreshDelaySeconds" is set to 3600 seconds, it
takes at most one hour from the time the file is updated for any configuration updates to be detected by
the server. If "refreshDelaySeconds" is set to 0, the server checks for configuration updates on every
request. Setting "refreshDelaySeconds" to a low value is not recommended for production environments,
as it could impact performance.
The Caching element also controls how many tenants' configurations are cached at once. You can set this
value to a number smaller than the total number of tenants to limit the amount of memory used to cache
the configuration information. If a request is received for a tenant not in the cache, the configuration is
loaded before the request can be processed. If the cache is full, the least recently used tenant is removed
from the cache.
If a change is saved to a configuration file or to any of the certificate files referenced within
flashaccess-tenant.xml while the server is attempting to read the file, or if the file's timestamp is found to
be less than one second before the current time or is in the future, the cached version of the configuration
is used until the next time the server checks for updates. If there is no cached version, the loading of the
configuration fails, and an error is returned to the client. The server attempts to load the file again the next
time it receives a request for that tenant.
Packaging content
When packaging content, the license server URL must be specified. The Flash Access Server URL has the
format:
http(s)://license-server-host:port/flashaccessserver/tenant-name
For example, for license server hostname "mylicenseserver.com" listening on port 8080 and a tenant
named "tenant1", the license server URL to specify at packaging time is:
http://mylicenseserver.com:8080/flashaccessserver/tenant1
If each tenant uses a different License Server and Transport Credential, be sure to specify the correct
tenant's certificate in the packager.
To ensure the server issues licenses only to content packaged by known packagers, include the packager's
certificate in the packager whitelist of the tenant configuration file.
Protecting Content
51
or the command:
java -jar libs/flashaccess-validator.jar options
For each of the license server configuration files, the Validator can perform file-based validation, which
ensures the XML file is well-formed and conforms to the configuration file schema. To perform file-based
validation on the global configuration file, run the command:
Validator --file path/flashaccess-global.xml --global
To perform file-based validation on the tenant configuration file, run the command:
Validator --file path/flashaccess-tenant.xml --tenant
The Validator can also perform deployment-based validation; in addition to checking conformity with the
schema, this level of validation also checks that the values specified are valid (for example, it ensures that
referenced files exist). Deployment-based validation can be performed at two levels:
Tenant Validates configuration file and credentials for a specific tenant. To validate the configuration
for "tenant1", run the command:
Validator --root-path-to-LicenseServer.ConfigRoot
-d flashaccessserver/tenant1 -t
Global Validates the global configuration file and tenant validation for all tenants. To perform global
deployment-based validation, run the command:
Validator --root-path-to-LicenseServer.ConfigRoot -g
Password Scrambler
The Password Scrambler utility encrypts a password so that it can be used in the Flash Access Server for
Protected Streaming configuration files. To run the scrambler, run the command:
Scrambler.bat password
or the command:
java -jar libs/flashaccess-scrambler.jar password
scrambled-password
Protecting Content
or the command:
java -jar libs/flashaccess-hasher.jar filename.swf
hash-of-swf
52
Command line tools for packaging content and creating revocation lists on page 53
Note: You should deploy either the Flash Access Server for Protected Streaming, the reference
implementation, or your own license server.
Media Packager: A tool for creating encrypted FLV and F4V files
Policy Update List Manager: A tool for creating and viewing policy update lists
Revocation List Manager: A tool for creating and viewing revocation lists
Requirements
The requirements for using the command line tools available in the reference implementations are as
follows:
Packager and License Server credentials (certificate and password) that are issued by Adobe. You need
credentials to encrypt and sign video files and to sign Policy Update and Revocation lists.
A 32-bit operating system. The tools are not officially supported on 64-bit operating systems (although
they may work).
Note: Because of a Java bug, arguments that are used on the command line, such as file names or policy
names or descriptions, must use characters only from the operating systems default character set.
Configuration file
The command-line tools require a configuration file that contains information for the tools to use to apply
policies and encrypt files.
The default configuration file is flashaccesstools.properties and is located in the working directory; that is,
the directory from which you run the tools (see Installing the command line tools). Each tool also contains
an option (-c) that lets you point to the configuration file you want to use if you prefer not to use the
default.
53
Protecting Content
54
The configuration file uses the Java property file format. If values for any of the properties contain special
characters, keep in mind the following restrictions:
Escape backslashes with an additional backslash. For example, to specify the C:\credentials.pfx file,
specify it as C:\\credentials.pfx or C:\credentials.pfx. To specify a file on a network server, specify
\\\\server\\folder\\filename.pfx.
The configuration file can contain only Latin-1 characters. If you must use non-Latin-1 characters, use
the appropriate Unicode escape sequence (using, optionally, the native2ascii tool that comes with
Java).
Set values for properties in the configuration file before you run the tools. For some of the command line
tools, you can set the values for some properties through either the command line or the configuration
file. In those cases, values that are set through the command line take precedence over any values in the
configuration file.
Policy Manager
Using Policy Manager, you can create and manage policies. Before you run Policy Manager, set values for
Policy Manager properties in the configuration file. The configuration file specifies information that will be
applied to all policies. All Policy Manager properties may also be specified on the command line.
Description
policy.name
policy.useRootLicense
Indicates whether this policy has a root license (see License Chaining
in the Usage Rules section of this document).
policy.startDate
The date after which content is valid. Use the format yyyy-mm-dd
(for example, 2009-01-31 represents January 31 at 12:00 AM) or
yyyy-mm-dd-h24:min:sec (for example, 2009-01-31-14:30:00
represents January 31 at 2:30 PM).
policy.expiration.endDate
Protecting Content
Policy Manager
Property
Description
policy.expiration.duration
The amount of time the content is valid (in minutes), starting from
when it is packaged. Both policy.expiration.endDate and
policy.expiration.duration may not be specified at the same time.
policy.licenseCaching.duration
policy.licenseCaching.endDate
policy.anonymous
policy.authNamespace
policy.customProp.n
policy.playbackWindow
Specifies the playback window (in minutes), which is the duration for
which the license is valid after the first time it is used to play
protected content.
policy.outputProtection.analog or
policy.outputProtection.digital
policy.drmMinSecurityLevel
The DRM module must have the specified minimum security level, or
higher, to access protected content.
policy.drmVersionBlacklist.n
A list of versions of DRM modules that may not be used (black list).
The property must use the following format:
os : stringValue
or:
release : stringValue
55
Protecting Content
Policy Manager
Property
Description
policy.runtimeVersionBlacklist.n
56
os : stringValue
or:
application : stringValue
or:
release : stringValue
policy.allowedSWFApplication.n
policy.license.customProp.n
The following table contains descriptions of the command line actions shown in the syntax above:
Command line action
Description
new
detail
update
The following table describes the command line options that can be specified along with the syntax
above:
Protecting Content
Policy Manager
57
Description
-c configfile
-n policyname
-o
-noprompt
-root
-e date
-r minutes
-s date
-w minutes
-l minutes
Protecting Content
Policy Manager
58
Description
-ldate date
The license caching end date (the date after which licenses
may not be cached in the client's License Store, after the
license has been issued by the server). Specify as
yyyy-mm-dd or yyyy-mm-dd-h24:min:sec. For example,
2008-12-1 or 2008-12-1-00:00:00 for midnight on December
1, 2008. Use -l without specifying a number of minutes for
unlimited license caching.
-authNS
-x
-air pubId[:appId[:[min]:[max]]]
-opAnalog NO_PROTECTION |
USE_IF_AVAILABLE | REQUIRED |
NO_PLAYBACK
-opDigital NO_PROTECTION |
USE_IF_AVAILABLE | REQUIRED |
NO_PLAYBACK
Protecting Content
Media Packager
59
Description
-swf url
-swf file=swf_file,
time=max_time_to_verify
-k name=value
-p name=value
Media Packager
Using Media Packager, you can specify what data in the file to encrypt and the policy to apply to the
content file. For example, you can specify that the video data is encrypted but the audio data is
unencrypted.
Description
encrypt.contents.video
encrypt.contents.audio
Protecting Content
Media Packager
60
Property
Description
encrypt.contents.script
encrypt.contents.video.level
encrypt.contents.secondsUnencrypted
encrypt.keys.asymmetric.certfile
The license server certificate file used to encrypt the key. The
encrypt.keys.asymmetric.certfile property specifies a file that
contains the certificate only (either PEM or DER format is
acceptable).
encrypt.keys.policyFile.n
encrypt.license.serverurl
encrypt.license.servercert
encrypt.sign.certfile
encrypt.sign.certpass
dest specifies where the encrypted content will be written. If a directory is specified, the encrypted file
will be saved in this folder using the same file name as the source file, but the directory must not be the
directory which contains the source file.
To encrypt multiple files with the same key (for multi-bit-rate support), use the following syntax:
java -jar AdobePackager.jar sourcefiles dest-directory [options]
Protecting Content
Media Packager
61
encrypted.
dest-directory specifies where the encrypted content will be written. The encrypted files will be
saved in this folder using the same file names as the source files, but the directory must not be the
directory that contains the source files.
The following table contains descriptions of the command line options shown in the syntax above:
Command line option
Description
-c configfile
-d encryptedfile
-e
-h
-i contentID
-k key= value
-m
-noprompt
-o
-p filename
Protecting Content
62
The following table contains descriptions of the command line options shown in the syntax above:
Command line option
Description
-c configfile
-d filename
-e date
-f filename
Adds all entries from the existing policy update list. Only one
existing file may be specified.
-noprompt
-o
Protecting Content
63
Description
Performs the same action as the -r flag, but extracts the policy
identifier from the given file.
-u policyFilename "reasonCode"
"reasonText" "reasonURL"
crlNumber is a non-negative version number of the CRL. This number should be incremented each
Description
-c configfile
-d filename
-e date
-f filename
Adds all entries from the existing revocation list. Only one
existing file may be specified.
Protecting Content
64
Description
-noprompt
-o
-r issuerName serialNumber
revocationDate
License Server:
Specifying multiple license server or transport credentials (after credentials are renewed, the old
credentials are kept on the server so existing content can be consumed without needing to
repackage)
Protecting Content
Requirements
Restricting time difference allowed between request time and server time (to prevent replay
attacks)
Handling requests from 1.x clients (triggers 1.x client to upgrade to 2.0)
Converting 1.x metadata to 2.0 metadata on the fly, using 1.x license information stored in a
database
Sample scripts for importing 1.x license information from an existing database
65
Packager Server:
Configuring the packager, creating policies, and creating policy update lists using an AIR
application
Requirements
You will need to ensure that you have the following installed:
Tomcat 6.0
Java 1.6
Once you have installed Tomcat and MySQL, obtain the credentials from Adobe.
Configuration
You will need to configure the server properties files, watched folder properties, set up the database, and
configure the HSM.
Protecting Content
Configuration
66
Note: The previous example uses a semicolon (;) as the delimiter. For platforms other than Microsoft
Windows, use a colon (:) as the delimiter.
The utility outputs the encrypted password, which you must copy to the .properties file.
Protecting Content
Configuration
67
If there is a configuration error in the packager properties file, the packager thread stops. To resume the
watched folder packager, restart the server. If there is a configuration error in a watched folder properties
file, the watched folder is temporarily removed from the list of folders the packager processes. To add the
watched folder back to the list, restart the server or modify the packager properties file. If an error occurs
during packaging of a particular file (for example, because the file is corrupt), the file is skipped and the
remaining files in the folder are processed.
User authentication
Metadata conversion
Delete the folder system drive \Documents and Settings\All Users\Application Data\MySQL.
Delete the old MySQL install folder: for example, system drive:\Program Files\MySQL\MySQL\Server
5.1.
Next, you will need to install MySQL JDBC Driver 5.1.7. To do this, copy mysql-connector-java-5.1.7-bin.jar
(found in the Third Party\MySQL\Installer\5.1 folder on the DVD) to Tomcat Server lib directory:
...\Tomcat6.0\lib.
Note: MySQL JDBC Driver 5.1.7 works with Tomcat 6.0. Older versions of Tomcat are not supported.
Set up the sample database by setting up the database schema and populating the database with sample
data. To do this, perform the following steps:
1. Go to Window's Start Menu, MySQL -> MySQL Server 5.1 -> MySQL Command Line Client.
2. After typing in the password, execute the following SQL script to add the user account dbuser for
establishing a connection through a web application and create database schema (make sure that
there is no ";" at the end. Just press enter.):
mysql> source Reference Implementation\Server\dbscript\createsampledb.sql
3. Edit the script that populates sample data in the tables to include data for your testing purposes:
Reference Implementation\Server\dbscript\PopulateSampleDB.sql.
Protecting Content
Configuration
68
HSM configuration
Use of an HSM is not required, but it is recommended. The reference implementation can be configured to
use the Sun PKCS11 provider for HSM support. In order to use a credential on an HSM, you must create a
configuration file for the Sun PKCS11 provider. See the Sun documentation for details. To verify that your
HSM and Sun PKCS11 configuration file are configured properly, you can use the following command
(keytool is installed with the Java JDK):
keytool -keystore NONE -storetype PKCS11
-providerClass sun.security.pkcs11.SunPKCS11 -providerArg pkcs11.cfg -list
If you see your credentials in the list, the HSM is configured properly.
Note: If you use a 64-bit version of Windows, HSM is currently not supported by the Reference
Implementation.
69
Troubleshooting
Listed below are common problems and solutions for deployment:
Make sure the password is encrypted using the provided ScrambleUtil class.
Make sure you specified the correct encrypted password for the PFX file.
Make sure you used the password scrambler class provided with the Reference Implementation (this
scrambler utility is different from the one provided with the Adobe Flash Access Server for
Protected Streaming).
Check your "AdobeFlashAccess.log" file. This is where the Reference Implementation writes log
information. The location of this log file is indicated by your log4j.xml file and can be modified to point
70
to any location youd like. By default, the log file will be output to the working directory where youve
run catalina.
Navigate to the following URL: http://your server:server port/flashaccess/license/v1. You should see the
text "License Server is setup correctly".
Another way to test if your server is running correctly is to package a piece of test content, set up a sample
video player, and play it. The following procedure describes this process:
1. Navigate to \Reference Implementation\Command Line folder. For information on installing the
command line tools, see Installing the command line tools on page 54.
2. Create a simple anonymous policy by using the following command:
java -jar libs\AdobePolicyManager.jar new policy_test.pol
For mor information on creating policies using the Policy Manager, see Command line usage on
page 56.
3. Set the encrypt.license.serverurl property in the flashaccesstools.properties file to the URL of
the license server (for example, http://localhost:8080/). The flashaccesstools.properties file is located
under the \Reference Implementation\Command Line Tools folder.
4. Package a piece of content by using the following command:
java -jar libs\AdobePackager.jar test_input_FLV output_file
Download-to-own (DTO)
Rental/Video-on-demand (VOD)
Subscription (all-you-can-eat)
Ad-funded
Protecting Content
71
To enable the usage model demo, specify the custom property "RI_UsageModelDemo=true" at packaging
time. If you are packaging content using the Media Packager command line tool, specify:
java -jar AdobeMediaPackager.jar source.flv dest.flv -k
RI_UsageModelDemo=true
Note: If you do not activate the optional demo mode at packaging time, the license server uses the policy
specified at packaging time to issue a license. If multiple policies were specified, the license server
uses the first valid policy.
In the demo, the business logic on the server controls the actual attributes of the licenses generated. At
packaging time, only minimal policy information must be included in the content. Specifically, the policy
only needs to indicate whether authentication is required to access the content. To enable all four usage
models, include one policy that allows anonymous access (for the Ad-funded model) and one policy that
requires user name/password authentication (for the other 3 usage models). When requesting a license, a
client application can determine whether to prompt the user for authentication based on the
authentication information in the policies.
To control the usage model under which a particular user is to be issued a license, entries may be added to
the Reference Implementation database. The Customer table contains user names and passwords for
authenticating users. It also indicates whether the user has a subscription. Users with subscriptions will be
issued licenses under the Subscription usage model. To grant a user access under the Download to Own or
Video on Demand usage models, an entry may be added to the CustomerAuthorization table, which
specifies each piece of content the user is allowed to access and the usage model. See the
PopulateSampleDB.sql script for details on populating each table.
When a user requests a license, the Reference Implementation server checks the metadata sent by the
client to determine if the content was packaged using the RI_UsageModelDemo property. If so, the
following business rules are used:
If the request contains a valid authentication token, look for the user in the Customer database
table. If the user was found:
Look for a record in the CustomerAuthorization database table for this user and content ID. If a
record was found:
If there is not a valid authentication token in the request, return an authentication required
error.
If one of the policies allows anonymous access, generate a license for the Ad-funded usage model and
send it to the user.
Before the Reference Implementation server can issue licenses for the usage model demo, the server
needs to be configured to specify how licenses are generated for each of the four usage models. This is
done by specifying a policy for each usage model. The Reference Implementation includes four sample
72
policies (dto-policy.pol, vod-policy.pol, sub-policy.pol, ad-policy.pol) or you may substitute your own
policies. In flashaccess-refimpl.properties, set the following properties to specify the policy to use for each
usage model and place the policy files in the directory specified by the config.resourcesDirectory
property:
# Policy file name for Download To Own usage
RefImpl.UsageModelDemo.Policy.DTO=dto-policy.pol
# Policy file name for Rental usage
RefImpl.UsageModelDemo.Policy.VOD=vod-policy.pol
# Policy file name for Subscription usage
RefImpl.UsageModelDemo.Policy.Subscribe=sub-policy.pol
# Policy file name for Ad Supported (free) usage
RefImpl.UsageModelDemo.Policy.Free=ad-policy.pol
Download-to-own
With the DTO usage model, a user may download the content for use online or offline and is issued a
permanent license for the content. When requesting a license, the user must authenticate so the server
can verify that the user has purchased the content.
Rental/Video-on-demand
With the VOD usage model content is offered with time-based restrictions. For example, a user has the
option to play the content during a 30-day period; however, once playback begins, the user has up to 48
hours to finish watching, after which time the content will no longer be playable. When requesting a
license, the user must authenticate so the server can verify that the user has a rental account.
Subscription
Some services offer paid subscriptions that give users unlimited access to a large library of content for as
long as they continue to pay the monthly fees. The license server issues a unique license for each piece of
content and also issues a root license whose expiration coincides with the subscription period. Each
month, when the user renews his subscription, the root license can also be renewed. When requesting a
license, the user needs to authenticate so the server can verify that the users subscription is up to date.
Ad-funded
Content is monetized by including advertising as part of the experience. With this model, content can be
distributed without requiring user authentication.
73
To import license information from LiveCycle ES into your Flash Access 2.0-based server, refer to the
sample database scripts provided in the Reference Implementation\Server\migration\db folder. Sample
scripts are provided for exporting the relevant data from a MySQL, Oracle, or SQL Server database into a
CSV file format. Once the data is exported, it can be imported into the database of your choice. The
exported license information includes the License ID, a Content ID assigned at packaging time, the ID of
the Policy used, the time the content was packaged, and the content encryption key. For 2.0, this
information is required in order to convert the 1.x content metadata into the 2.0 metadata format (see
FMRMSv1RequestHandler and FMRMSv1MetadataHandler). In the reference implementation, this
data is stored in the License database table and used by RefImplMetadataConvReqHandler.
Existing policies will need to be converted to the Flash Access 2.0 format in order to use those policies
when converting metadata and issuing licenses for 1.0 or 1.5 content. The Reference
Implementation\Server\migration folder contains sample code for creating a 2.0 policy based on older
policies.
If you are migrating from FMRMS 1.0 to Flash Access 2.0, see the V1_0PolicyConverter.java sample.
Compile the sample code by running "ant-f build-migration.xml build-1.0-converter" (the script expects
the 1.0 and 2.0 libraries to be in libs/1.0 and libs/2.0 respectively). Edit the converter.properties file to point
to your LiveCycle ES server. Then run "ant -f build-migration.xml migrate-all-1.0-policies" to convert all
FMRMS 1.0 policies to 2.0 format.
If you are migrating from FMRMS 1.5 to Flash Access 2.0, see the V1_5PolicyConverter.java sample.
Compile the sample code by running "ant-f build-migration.xml build-1.5-converter" (the script expects
the 1.5 and 2.0 libraries to be in libs/1.5 and libs/2.0 respectively). Edit the converter.properties file to point
to your LiveCycle ES server. Then run "ant -f build-migration.xml migrate-all-1.5-policies" to convert all
FMRMS 1.5 policies to 2.0 format.
The converted policies will be written to a set of files. In addition, PolicyConverter will output a CSV file
containing the mapping of old policy IDs to new policy IDs. This file can be imported into the
"PolicyConversion" table in the reference implementation database, and will be used by
RefImplMetadataConvReqHandler.
Once the relevant data has been migrated to your Flash Access 2.0-based server, you are ready to
implement support for 1.x compatibility requests. See RefImplUpgradeV1ClientHandler and
RefImplMetadataConvReqHandler in the reference implementation for examples of how to process
these types of requests.
Protecting Content
74
Running amxmlc produces FlashAccessManager.swf, which contains the compiled code of the
application. For more information see,
http://livedocs.adobe.com/flex/3/html/help.html?content=CommandLineTools_5.html.
The Adobe AIR SDK includes the AIR Developer Tool (ADT) utility to package AIR applications and generate
certificates. AIR applications should be digitally signed; users will receive a warning when installing
applications that are not properly signed or are not signed at all. To generate a certificate using the
command line, open a console window in the same folder as your AIR application and type the following:
adt -certificate -cn SelfSigned 1024-RSA testCert.pfx some_password
Substitute some_password with a password of your choice. After a few seconds, ADT should complete its
certificate generation process and you should have a new testCert.pfx file in your application directory.
Next, use ADT to package the application into an .air file, by using the command:
adt -package -storetype pkcs12 -keystore testCert.pfx FlashAccessManager.air
src\FlashAccessManager-app.xml . -C src assets
This command tells ADT to package your application, using the key file in testCert.pfx. In the line above,
you configure ADT to package your entire application into a file named FlashAccessManager.air, and to
include the files FlashAccessManager-app.xml and FlashAccessManager.swf and the images from the
assets directory.
As part of this process, you'll be prompted for the password that you set for your new certificate file. Enter
it, wait a moment, and a FlashAccessManager.air file should appear in the same directory as your project
files.
Protecting Content
Setting preferences
75
1. Deploy the Packager Server. This server should only be available to users within your firewall (do not
deploy this software on a public-facing machine). For more information on deploying the server, see
Deploying the license server and watched folder packager on page 69.
Start the server. You will see some errors due to problems in the properties file; this is expected
since the properties have not been filled in yet.
2. Install the Adobe Flash Access Manager AIR application by launching the .air file (requires AIR 1.5 or
higher).
3. Launch the Adobe Flash Access Manager AIR application.
If your server is running somewhere other than http://localhost:8080, you see errors stating that the
application cannot connect to the server. Dismiss the error dialog and fill in the correct URL for the
"Packager Server URL" in the Preferences Tab. If the server is running at the specified URL and the
properties file is on the classpath, the Preferences screen will be populated with the values in the
properties file. After you set the packager server URL, the AIR application remembers this setting, and
you will not have to enter it the next time you launch the application.
4. Fill in the values in the Preferences tab and click Save. For an explanation of each parameter, see
Setting preferences on page 75.
5. If you want to use the Watched Folders, you will need to restart the server to recover from the errors
you saw in step 3. If the preferences are configured properly, no errors should appear during startup.
Setting preferences
With the exception of the Packager Server URL, all the preferences specified below are stored in the
flashaccess-refimpl-packager.properties file on the server. All the settings can be modified either directly
in the properties file or through the AIR application. Passwords are encrypted when they are stored in the
properties file on the server. Type the unencrypted password into the UI, and it will be encrypted before it
is stored in the file.
Note: All directories and paths refer to directories on the packager server, not on the client running the
AIR application.
Any changes made here take effect immediately once the preferences are saved. There is no need to
restart the server unless the Packager Thread terminated due to configuration problems.
The preference descriptions use the following terms:
Term
Description
Packager Preferences
This tab contains settings required for packaging content. The following table describes these preferences:
Protecting Content
Preference
Setting preferences
Preference
Preference
76
Description
Enable HSM
Packager Credential
File Name
File Password
Protecting Content
Preference
Setting preferences
Preference
Preference
77
Description
Input Backup
Subfolder Name
Overwrite Existing
Output Files
Description
License Server Credential The License Server credential, issued by Adobe. This credential is used to
sign Policy Update Lists.
File Name
The PKCS#12 (.pfx) file containing certificate and private key. The file must
be located in the Resource Directory.
File Password
HSM Preferences
Preferences in this tab only need to be specified if the "Enable HSM" checkbox is selected in the Packager
tab. The following table describes these preferences:
Preference
Description
The full path to the Sun PKCS#11 provider's configuration file. See the
Java PKCS#11 Reference Guide on Sun's website for details on the
contents of this configuration file.
Partition Password
Protecting Content
Policy creation
78
Preference
Description
Policy creation
Before any content can be packaged, one or more policies must be created. For an overview of the usage
rules that may be specified in a policy, see Usage rules on page 7.
Preference
Policy Duration
Description
Specifies the validity period of content protected with
this policy.
Start at
End at
End after
License Caching
Delete after
Cache Indefinitely
No License Caching
Anonymous
Authentication
Protecting Content
Preference
Policy creation
Preference
Description
Authenticated
79
Play Rights
The following table describes the Play Rights preferences:
Preference
Preference
Description
Playback Window
The duration a license is valid (in minutes) after the first time
the user plays the protected content.
Output Protection
Restrictions
Runtime
DRM
Runtime
Allowed Applications
AIR
Flash Access Manager supports policies containing multiple Play Rights. To create a policy with more than
one Play Right, use the "Add additional Play Right" button, and fill in the desired attributes for each Play
Right.
When consuming a license, the client uses the first Play Right for which it meets all the requirements.
Multiple play rights may be used to specify different restrictions for different operating systems. For
example, it is possible to specify one right with Output Protection required for Windows (by blacklisting
Protecting Content
80
DRM versions on Macintosh and Linux) and to specify a second right with Output Protection "Use if
available" on other platforms (by blacklisting DRM versions on Windows).
Custom Data
The following table describes the Custom Data preferences:
Preference
Description
Specify custom properties, which the license server may use when issuing
licenses.
Custom License Properties Specify custom properties, which will appear in the license issued to the
client. Client applications will have access to these properties.
Delete a policy
To delete an existing policy, choose the filename from the drop down list and click Delete.
Protecting Content
Package media
81
Package media
Use the Package Media tab to package content. The Packager Properties section displays the Packager
settings that were entered in the Preferences tab. To modify these settings, go to the Preferences tab,
change the settings, and Save.
If you want to package a single FLV or F4V file, choose the "Select Single File" option and enter the full path
to the source file and full path where the encrypted file should be saved.
If you want to package all files in a folder, choose the "Select Single Folder" option. Specify the folder
containing the source files. Only files in the Input Folder matching the "Input Media File Selection" criteria
will be packaged (files in subfolders are not packaged). Choose to encrypt .flv files, .f4v files, or enter a
custom regular expression (for example ".*" encrypts all files in the folder). The encrypted files will be saved
in the specified output folder, using the same filename as the original file.
Note: File paths must refer to files available to the packaging server. If you are running the Flash Access
Manager on a different machine than the packaging server, you must specify a path that is
accessible by the server (either located on a network drive or on the server itself ).
The following table describes the Package Media preferences:
Preference
Description
Select one or more policies from the drop-down list to apply to the content. To
select multiple policies, hold down the CTRL key while selecting policies.
Seconds Unencrypted Specifies the number of seconds of content to leave unencrypted at the
beginning of the file. To encrypt starting from the beginning, enter "0".
Encrypt Video
Encryption Level
If video encryption is enabled, select the encryption level for video data. High
encrypts all video data. Medium and Low selectively encrypt portions of the
video. (Only for F4V with H.264 video)
Encrypt Audio
Encrypt Script
Custom Properties
After the packaging options are selected, click the "Package Media" button to begin packaging the files.
Watched Folders
You can use Watched Folders to automatically package content created in certain folders. Each Watched
Folder can be configured with different packaging options. To test packaging options before creating a
Watched Folder, use the Package Media tab.
To create a Watched Folder, click "Add New Watched Folder" and fill in the packaging options. See the
"Package Media" section for a description of each option. When done, click "Save Watched Folder
Properties".
82
When a Watched Folder is saved, the packaging options are saved to [Input
Folder]\packager\watchfolder.properties. Any content added to the Input Folder which meets the Input
Media File Selection criteria will automatically be packaged and placed in the Output Folder. See the
Global Watched Folder Preferences in the section Packager Preferences on page 75 to configure
additional Watched Folder options.
To modify Watched Folder settings, select the Watched Folder input path from the list at the top of the
screen. Modify the settings and click "Save Watched Folder Properties".
To delete a Watched Folder, select the Watched Folder input path from the list at the top of the screen and
click "Delete Watched Folder Properties".