Code signing
Code signing is the process of digitally signing executables and scripts to confirm the software author and guarantee that the code has not been altered or corrupted since it was signed by use of a cryptographic hash.
Code signing can provide several valuable features. The most common use of code signing is to provide security when deploying; in some programming languages, it can also be used to help prevent namespace conflicts. Almost every code signing implementation will provide some sort of digital signature mechanism to verify the identity of the author or build system, and a checksum to verify that the object has not been modified. It can also be used to provide versioning information about an object or to store other meta data about an object.[1]
Providing security
Many code signing implementations will provide a way to sign the code using a system involving a pair of keys, one public and one private, similar to the process employed by SSL or SSH. For example, in the case of .NET, the developer uses a private key to sign their libraries or executables each time they build. This key will be unique to a developer or group or sometimes per application or object. The developer can either generate this key on their own or obtain one from a trusted certificate authority (CA).[2]
Code signing is particularly valuable in distributed environments, where the source of a given piece of code may not be immediately evident - for example Java applets, ActiveX controls and other active web and browser scripting code. Another important usage is to safely provide updates and patches to existing software. Windows, Mac OS X, and most Linux distributions provide updates using code signing to ensure that it is not possible for others to maliciously distribute code via the patch system. It allows the receiving operating system to verify that the update is legitimate, even if the update was delivered by third parties or physical media (disks).
Code signing is used on Windows and Mac OS X to authenticate software on first run, ensuring that the software has not been maliciously tampered with by a third-party distributor or download site. This form of code signing is not used on Linux because of that platform's decentralized nature, the package manager being the predominant mode of distribution for all forms of software (not just updates and patches), as well as the open source model allowing direct inspection of the source code if desired.
Trusted identification using a certificate authority (CA)
The public key used to authenticate the code signature should be traceable back to a trusted root authority CA, preferably using a secure public key infrastructure (PKI). This does not ensure that the code itself can be trusted, only that it comes from the stated source (or more explicitly, from a particular private key).[3] A CA provides a root trust level and is able to assign trust to others by proxy. If a user trusts a CA, then the user can presumably trust the legitimacy of code that is signed with a key generated by that CA or one of its proxies. Many operating systems and frameworks contain built-in trust for one or more existing CAs (such as StartCom, VeriSign/Symantec, DigiCert, TC TrustCenter, Comodo, GoDaddy and GlobalSign). It is also commonplace for large organizations to implement a private CA, internal to the organization, which provides the same features as public CAs, but it is only trusted within the organization.
Alternative to CAs
The other model is where developers can choose to provide their own self-generated key. In this scenario, the user would normally have to obtain the public key in some fashion directly from the developer to verify the object is from them for the first time. Many code signing systems will store the public key inside the signature. Some software frameworks and OSs that check the code's signature before executing will allow you to choose to trust that developer from that point on after the first run. An application developer can provide a similar system by including the public keys with the installer. The key can then be used to ensure that any subsequent objects that need to run, such as upgrades, plugins, or another application, are all verified as coming from that same developer.
Time-Stamping
Time-stamping was designed to circumvent the trust warning that will appear in the case of an expired certificate. In effect, time-stamping extends the code trust beyond the validity period of a certificate.[4]
In the event that a certificate has to be revoked due to a compromise, time-stamping can provide a specific date and time that the certificate will revert to.
Problems
Like any security measure, code signing can be defeated. Users can be tricked into running unsigned code, or even into running code that refuses to validate, and the system only remains secure as long as the private key remains private.[5][6]
It is also important to note that code signing does not protect the end user from any malicious activity or unintentional software bugs by the software author - it merely ensures that the software has not been modified by anyone other than the author.
Implementations
IBM's Lotus Notes has had PKI signing of code from Release 1, and both client and server software have execution control lists to control what levels of access to data, environment and file system are permitted for given users. Individual design elements, including active items such as scripts, actions and agents, are always signed using the editor's ID file, which includes both the editor's and the domain's public keys. Core templates such as the mail template are signed with a dedicated ID held by the Lotus template development team.
Microsoft implements a form of code signing (based on Authenticode) provided for Microsoft tested drivers. Since drivers run in the kernel, they can destabilize the system or open the system to security holes. For this reason, Microsoft tests drivers submitted to its WHQL program. After the driver has passed, Microsoft signs that version of the driver as being safe. On 32-bit systems only, installing drivers that are not validated with Microsoft is possible after accepting to allow the installation in a prompt warning the user that the code is unsigned. For .NET (managed) code, there is an additional mechanism called Strong Name Signing that uses Public/Private keys and SHA-1 hash as opposed to certificates. However, Microsoft discourages reliance on Strong Name Signing as a replacement for Authenticode.[7]
Unsigned code in gaming and consumer devices
In the context of consumer devices such as games consoles, unsigned code is often used to refer to an application which has not been signed with the cryptographic key normally required for software to be accepted and executed. Most console games have to be signed with a secret key designed by the console maker or the game will not load on the console. There are several methods to get unsigned code to execute which include software exploits, the use of a modchip, a technique known as the swap trick or running a softmod.
It may not initially seem obvious why simply copying a signed application onto another DVD does not allow it to boot. On the Xbox, the reason for this is that the Xbox executable file (XBE) contains a media-type flag, which specifies the type of media that the XBE is bootable from. On nearly all Xbox software, this is set such that the executable will only boot from factory produced discs so simply copying the executable to burnable media is enough to stop the execution of the software.
However, since the executable is signed, simply changing the value of the flag is not possible as this alters the signature of the executable causing it to fail validation when checked.
Trusted-Library Attribute
For applications and applets that are designed to allow unsigned components, the Trusted-Library attribute should be used. No warning dialog will be displayed and an application or applet may load jar files containing untrusted classes or resources. This attribute prevents signed components in an application or applet from being re-purposed with unsigned components. You can specify Trusted-Library: true in the manifest file. For example:
Manifest-Version: 1.0 Trusted-Library: true Created-By: 1.6.0-internal (Sun Microsystems Inc.)
All classes and resources in a jar file containing this manifest attribute must be signed and trusted.
References
- ↑ Hendric, William (2015). "A Complete overview of Trusted Certificates - CABForum" (PDF). Retrieved 2015-02-26.
- ↑ Hendric, William (17 June 2011). "What is Code Signing?". Retrieved 26 February 2015.
- ↑ https://casecurity.org/wp-content/uploads/2013/10/CASC-Code-Signing.pdf
- ↑ Morton, Bruce. "Code Signing" (PDF). CASC. Retrieved 21 February 2014.
- ↑ http://blog.trendmicro.com/fake-antivirus-solutions-increasingly-stolen-code-signing-certificates/
- ↑ http://www.eweek.com/c/a/Security/Theres-A-Racket-Brewing-In-the-Code-Signing-Cert-Business/
- ↑ Strong Name Bypass: .NET Security Blog
See also
- Digital signature
- iOS jailbreaking
- PlayStation Portable homebrew
- Privilege escalation
- Rooting (Android OS)
- Symbian OS Security bypass
External links
- Apple Code Signing Guide
- Microsoft Introduction to Code Signing
- Debian Security Infrastructure
- Strong Name and Code Sign .Net assemblies with signIT! by Cove Bay Software
- Strong Distribution HOWTO